【数据结构】最小瓶颈路 加强版(Kruskal重构树RMQ求LCA)
题目描述
给定一个 n 个点 m 条边的无向连通图,编号为 1 到 n ,没有自环,可能有重边,每一条边有一个正权值 w 。
给出 q 个询问,每次给出两个不同的点 u 和 v ,求一条从 u 到 v 的路径上边权的最大值最小是多少。
输入格式
输入第一行两个整数 n, m。
接下来 m 行,每行三个整数 ai, bi, wi (ai != bi),表示一条边 (ai, bi),边权为 wi。
接下来一行一个整数 q,表示询问数量。
接下来一行四个整数 A,B,C,P,表示询问的生成方式。
由于本题数据规模较大,直接输入输出会占用比计算多数倍的时间,因此对询问的输入输出进行了压缩。
输入压缩方法是:读入4个整数 A,B,C,P,每次询问调用以下函数生成 u 和 v:
int A,B,C,P;
inline int rnd(){return A=(A*B+C)%P;}
每次询问时的调用方法为:
u=rnd()%n+1,v=rnd()%n+1;
若u和v相等则答案为0。
数据保证 0<=A<P,0<=C<P,P(B+1)<2^31-1
输出格式
输出共一行一个整数,表示所有询问的答案之和模 1000000007 的值。
由于本题数据规模较大,直接输入输出会占用比计算多数倍的时间,因此对询问的输入输出进行了压缩。
输出压缩方法是:输出所有询问的答案之和模 1000000007 的值。
样例
输入
5 7
1 2 8
2 3 9
3 1 2
3 4 7
1 4 4
3 5 6
1 4 9
10
233 17 66666 19260817输出
32
数据范围与提示
思路
首先可以证明,两点之间边权最大值最小的路径一定是在最小生成树上。考虑到这题是边权的最大值,直接把重构树建出来,然后查LCA处的权值即可。由于输入文件过大,需要用RMQ算法求LCA。
AC_Code
#include <bits/stdc++.h>
const int MAXN=1e6+10, mod=1e9+7;
using namespace std;inline int read() {char c=getchar();int x=0, f=1;while (c<'0' || c>'9') {if(c=='-') f=-1;c=getchar();}while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();return x*f;
}int N,M,fa[MAXN],tot,val[MAXN],id[MAXN][21],num,dfn[MAXN],dep[MAXN],lg2[MAXN];struct Edge {int u, v, w;bool operator<(const Edge &rhs) const { return w < rhs.w; }
} E[MAXN];vector<int> v[MAXN];int find(int x) {return fa[x]==x?fa[x]:fa[x]=find(fa[x]);}void Kruskal()
{for (int i=1; i<=2*N; i++) fa[i]=i;tot = N;for(int i=1; i<=M; i++) {int x = find(E[i].u), y = find(E[i].v);if(x==y) continue;val[++tot] = E[i].w;v[tot].push_back(x);v[tot].push_back(y);v[x].push_back(tot);v[y].push_back(tot);fa[x] = tot;fa[y] = tot;}
}void dfs(int x, int fa)
{dfn[x] = ++num;dep[x] = dep[fa]+1;id[num][0] = x;for (int i=0, to; i<v[x].size(); i++) {if((to=v[x][i])==fa) continue;dfs(to, x);id[++num][0] = x;}
}void RMQ() {for(int i=2; i<=num; i++) lg2[i] = lg2[i>>1] + 1;for(int j=1; j<=20; j++)for(int i=1; i+(1<<j)-1<=num; i++) {int r = i+(1<<(j-1));id[i][j] = (dep[id[i][j-1]] < dep[id[r][j-1]]) ? id[i][j-1] : id[r][j-1];}
}int A, B, C, P;
inline int rnd() { return A = (A*B+C) % P; }int LCA(int x, int y) {x = dfn[x];y = dfn[y];if (x > y)swap(x, y);int k = lg2[y - x + 1];return dep[id[x][k]] < dep[id[y - (1 << k) + 1][k]] ? id[x][k] : id[y - (1 << k) + 1][k];
}int main() {N = read();M = read();for (int i = 1; i <= M; i++) {int x = read(), y = read(), z = read();E[i] = (Edge){ x, y, z };}sort(E + 1, E + M + 1);Kruskal();dfs(tot, 0);RMQ();int ans = 0, Q = read();A = read(); B = read();C = read(); P = read();while (Q--) {int u = rnd() % N + 1, v = rnd() % N + 1;(ans += val[LCA(u, v)]) %= mod;}printf("%d", ans);return 0;
}
【数据结构】最小瓶颈路 加强版(Kruskal重构树RMQ求LCA)相关推荐
- bzoj3551 [ONTAK2010]Peaks加强版 kruskal重构树
最大边最小,就是最小生成树,可以考虑用主席树维护father数组,但不能遍历子集查找 然后就只能牺牲一部分空间时间来多存一些东西 多存的就是边值大小顺序,本来以为是用主席树排边值,结果由于此题有2种数 ...
- [ONTAK2010] Peaks加强版 (kruskal重构树+主席树+倍增)
Peaks description solution code description 在Bytemountains有N座山峰,每座山峰有他的高度h_i 有些山峰之间有双向道路相连,共M条路径,每条路 ...
- Kruskal重构树
构建方法 把生成树的每个边拆成一个点表示,点权即为原来的边权,添加两个边指向原来的点.这样kruskalkruskalkruskal重构树就有2∗n−12*n-12∗n−1个点 性质 叶子节点对应之前 ...
- kruskal 重构树(讲解 + 例题)
kruskal重构树 如何建树 模仿kruskalkruskalkruskal,先将所有边排序. 依次遍历每一条边,如果这条边的两个节点(u,vu, vu,v)不在同一个连通块里面, 则新建一个nod ...
- LOJ.2865.[IOI2018]狼人(Kruskal重构树 主席树)
LOJ 洛谷 这题不就是Peaks(加强版)或者归程么..这算是\(IOI2018\)撞上\(NOI2018\)的题了? \(Kruskal\)重构树(具体是所有点按从小到大/从大到小的顺序,依次加入 ...
- Kruskal重构树 学习笔记
Kruskal重构树 学习笔记 文章目录 Kruskal重构树 学习笔记 前言 例题1 BZOJ3732 Network 例题2 [NOI2018] 归程 前言 Kruskal重构树是一种比较冷门的算 ...
- P1967 货车运输( 最大生成树+LCA or Kruskal重构树)
至于为什么要用最大生成树!? 理由:因为问最大载重,如果要加大载重的话,对于选择的路肯定权重越大越好,所以贪心地想,得用到最大生成树.然后两点之间的最大载重用LCA去寻找就可以了. 最大生成树+LCA ...
- 洛谷P4768 [NOI2018]归程(Kruskal重构树)
题意 直接看题目吧,不好描述 Sol 考虑暴力做法 首先预处理出从$1$到每个节点的最短路, 对于每次询问,暴力的从这个点BFS,从能走到的点里面取$min$ 考虑如何优化,这里要用到Kruskal重 ...
- [NOI2018] 归程(线段树维护并查集的可持久化/kruskal重构树,倍增+dijkstra最短路)
[NOI2018] 归程 description solution1 code1 solution2 code description 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要 ...
最新文章
- 电脑温度检测软件哪个好_一般电脑录音软件哪个好?
- -16 | 12 等于多少
- python进程监控并重启
- 平衡二叉树平衡因子_数据结构:平衡二叉树
- .NET EFCore之增删改查
- Java黑皮书课后题第6章:*6.21(电话按键盘)国际标准的字母/数字匹配图如编程练习题4.15所示。编写一个测试程序,提示用户输入字符串形式的电话号码。程序将字母(大写或小写)翻译成数字
- HTML5 CSS3初学者指南(3) – HTML5新特性
- 围成一圈的排列组合问题_分班必考知识点!小学奥数之排列组合问题
- vue --- 子组件监听点击事件,接收父组件参数.实现对应跳转
- NOIP模拟测试29「爬山·学数数·七十和十七」
- 解决:-source 1.6 中不支持 diamond 运算符 [ERROR] (请使用 -source 7 或更高版本以启用 diamond 运算符)
- 兵乓球- 经典街机游戏-python小游戏源码下载
- Spring使用Cache、整合Ehcache
- easyui获取图片路径_094 ego电商项目-2 菜单、图片上传、CRUD
- KMP模式匹配算法——C++
- 免费的录屏软件Capture
- 上三角、下三角、对称矩阵
- 通过图书编号查询python_基于Python的图书ISBN查询接口调用代码实例
- Vue+element+Nodejs学习记录(6)
- PC/UVa 题号: 110106/10033 Interpreter (解释器)题解 c语言版
热门文章
- C++初学者必练基础编程题【第一期】
- 爬虫-东北林业大学校内-中国[哈尔滨]森林博物馆-爬取所有馆藏蝴蝶图片
- vue-cli3打包时图片压缩处理
- 关于0x80070091 目录不是空的
- Mac下eclipse安装和配置Tomcat
- Android NFC基础
- java mysql连接池配置_Java数据库连接池的几种配置方法(以MySQL数据库为例)
- IntelliJ IDEA中怎么查看方法说明
- 奶酪巫师的黑客乐园 - 第一个进行硬分叉的区块链游戏?
- 行走在思想的边上――武墩支教十二月(上)