BZOJ3732: Network(Kruskal重构树)
题意
给出一张$n$个点的无向图,每次询问两点之间边权最大值最小的路径
$n \leqslant 15000, m \leqslant 30000, k \leqslant 20000$
Sol
很显然答案一定在最小生成树上,但是此题还有一个更为玄学的做法—Kruskal重构树
它是在Kruskal算法上改进而来的。
算法流程:
- 对于此题来说,将边权从小到大排序
- 用并查集维护两点的联通性,若祖先不相同,那么新建一个节点,权值为边权。左右儿子分别为两个点
这样建出来的树,我们称之为Kruskal重构树
它有许多美妙的性质
- 是一颗二叉树
- 两点的LCA的点权为原图中最大值最小的路径上的最大值
- 任意点的权值大于左右儿子的权值,是一个大根堆
对于此题的样例来说,建出来的图大概长这样

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 1e5 + , INF = 1e9, B = ;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int fa[MAXN], f[MAXN][], ch[MAXN][], cnt, val[MAXN], deep[MAXN];
int N, M, K;
struct Edge {
int u, v, w;
bool operator < (const Edge &rhs) const {
return w < rhs.w;
}
}E[MAXN];
int head[MAXN], num = ;
inline void AddEdge(int x, int y, int z) {
E[++num] = (Edge){x, y, z};
}
int find(int x) {
if(fa[x] == x) return fa[x];
else return fa[x] = find(fa[x]);
}
void Kruskal() {
sort(E + , E + num + );
int tot = ;
for(int i = ; i <= M; i++) {
int x = E[i].u, y = E[i].v;
int fx = find(x), fy = find(y);
if(fx == fy) continue;
ch[++cnt][] = fx, ch[cnt][] = fy;
fa[fa[x]] = fa[fa[y]] = f[fa[x]][] = f[fa[y]][] = cnt;
val[cnt] = E[i].w; }
}
void dfs(int x) {
if(!ch[x][] && !ch[x][]) return ;
deep[ch[x][]] = deep[ch[x][]] = deep[x] + ;
dfs(ch[x][]); dfs(ch[x][]);
}
int LCA(int x, int y) {
if(deep[x] < deep[y]) swap(x, y);
for(int i = B; i >= ; i--)
if(deep[f[x][i]] >= deep[y])
x = f[x][i];
if(x == y) return x;
for(int i = B; i >= ; i--)
if(f[x][i] != f[y][i])
x = f[x][i], y = f[y][i];
return f[x][];
}
main() {
//freopen("a.in", "r", stdin);
cnt = N = read(); M = read(); K = read();
for(int i = ; i <= N << ; i++) fa[i] = i;
for(int i = ; i <= M; i++) {
int x = read(), y = read(), z = read();
AddEdge(x, y, z);
}
Kruskal();
deep[cnt] = ; dfs(cnt);
for(int i = ; i <= B; i++)
for(int j = ; j <= * N; j++)
f[j][i] = f[f[j][i - ]][i - ];
while(K--) {
int x = read(), y = read();
// printf("%d\", LCA(x, y));
printf("%d\n", val[LCA(x, y)]);
}
return ;
}
BZOJ3732: Network(Kruskal重构树)的更多相关文章
- [bzoj 3732] Network (Kruskal重构树)
kruskal重构树 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1-N. 图中有M条边 (1 <= M <= 30,000) ,第 ...
- 【BZOJ 3732】 Network Kruskal重构树+倍增LCA
Kruskal重构树裸题, Sunshine互测的A题就是Kruskal重构树,我通过互测了解到了这个神奇的东西... 理解起来应该没什么难度吧,但是我的Peaks连WA,,, 省选估计要滚粗了TwT ...
- BZOJ3732 (Kruskal重构树)
Kruskal重构树上\(x\)和\(v\)的\(lca\)的权值即为它们最长路最小值 #include <cstdio> #include <iostream> #inclu ...
- BZOJ 3732: Network Kruskal 重构树
模板题,练练手~ Code: #include <cstdio> #include <algorithm> #define N 80000 #define setIO(s) f ...
- Kruskal重构树学习笔记+BZOJ3732 Network
今天学了Kruskal重构树,似乎很有意思的样子~ 先看题面: BZOJ 题目大意:$n$ 个点 $m$ 条无向边的图,$k$ 个询问,每次询问从 $u$ 到 $v$ 的所有路径中,最长的边的最小值. ...
- BZOJ3732 Network(Kruskal重构树)
Kruskal重构树的模板题. 给你N个点的无向图 (1 <= N <= 15,000),记为:1-N.图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: ...
- 【BZOJ】3732: Network【Kruskal重构树】
3732: Network Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2812 Solved: 1363[Submit][Status][Dis ...
- BZOJ 3732 Network 【模板】kruskal重构树
[题解] 首先,我们可以发现,A到B的所有路径中,最长边的最小值一定在最小生成树上.我们用Kruskal最小生成树时,假设有两个点集U,V,若加入一条边w(u,v)使U,V联通,那么w就是U中每个点到 ...
- Kruskal重构树+LCA || BZOJ 3732: Network
题面:https://www.lydsy.com/JudgeOnline/problem.php?id=3732 题解:Kruskal重构树板子 代码: #include<cstdio> ...
随机推荐
- hdu5072 容斥+枚举
这题说的是给了 n 个数字 每个数值大于1 小于100000,n小于100000 ,找出满足下面要求的三人组有多少种 比如abc ( (ab)==(bc)==(ac) ==1 )||( (ab)!=1 ...
- echarts 饼状图 改变折线长度
$(function (){ //ups部分 var myChart = echarts.init(document.getElementById('result')) var option = { ...
- 20155305乔磊2016-2017-2《Java程序设计》第九周学习总结
20155305 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 JDBC入门 JDBC简介 1.JDBC是java联机数据库的标准规范,它定义了一组标准类与 ...
- Web安全之BurpSuite抓取HTTPS请求
出现了问题,第一步要干什么呢? 当然是要去官方网站去找FAQ和help,先来练习一下英语 https://portswigger.net/burp/help/proxy_options_install ...
- 在apache中使用.htaccess文件的注意事项
在apache的配置文件中: <VirtualHost *:80> ServerName tp5.com DocumentRoot d:/wamp/www/tp5.com/public & ...
- js中fn()和return fn()的区别
参考文章:http://www.jb51.net/article/87977.htm 这文章中没有讲明白,其实只要把文章里的代码加和不加return调试一下就知道是怎么回事了. var i = 0; ...
- Cache与主存地址映像计算例题
一.全相连映像 主存中任何一个块均可以映像装入到Cache中的任何一个块的位置上.主存地址分为块号和块内地址两部分,Cache地址也分为块号和块内地址.Cache的块内地址部分直接取自主存地址的块内地 ...
- 子网掩码与ip有实际关系吗?
子网掩码是作为ip地址的标识,还是本身就是ip地址的一部分?例如10.10.10.1/24和10.10.10.1/25是同一个ip地址吗? 作者:知乎用户链接:https://www.zhihu.co ...
- linux中find与rm实现查找并删除目录或文件
linux 下用find命令查找文件,rm命令删除文件. 删除指定目录下指定文件find 要查找的目录名 -name .svn |xargs rm -rf 删除指定名称的文件或文件夹: find -t ...
- zoj Candies 思维
http://acm.zju.edu.cn/changsha/showProblem.do?problemId=31 题意: 给你n个非负整数,然后输入n个x[i],x[i] == -1表示第i个数不 ...