Borůvka MST算法
当我认为最MST(最小生成树)已经没有什么学的了,才发现世界上还有个这个kruskal和prim结合的玩意
Borůvka 运用并查集的思想,先将每一个初始点集初始化为有且只有自己的点集,然后每一次合并都从所有的独立集合出发,找到一条权值最小的(权值相同,则编号最小)连向其他集合的边,然后合并集合,很容易看出,每次合并都会使集合总数少一半,合并次数大致为log n
相比之下,Borůvka的合并次数要远远少于其他两个常用的MST算法,但是,毕竟不是一般情况下最快的,但是在求解一些个别的(例如边数多,点数较少的完全图)问题有奇效
luogu MST的例题,过不去,最后一个点会T,毕竟Borůvka是用来解决完全图的,并不是一般情况下最快的
1 #include "bits/stdc++.h"
2 using namespace std;
3 #define LL long long
4 const int N = 2e5 + 10;
5 int n,m;
6 int s[N],t[N],w[N];
7 struct Boruvka
8 {
9 int f[N],use_edge[N],best[N];
10 void init()
11 {
12 for(int i = 1;i <= n;i ++) f[i] = i,best[i] = 0;
13 for(int i = 1;i <= m;i ++) use_edge[i] = 0;
14 }
15 int find(int x)
16 {
17 return f[x] == x ? x : (f[x] = find(f[x]));
18 }
19 int better(int x,int y)
20 {
21 if(!y) return 1;
22 if(w[x] < w[y]) return 1;
23 return x < y;
24 }
25 LL get(void)
26 {
27 int merge=0;
28 LL sum=0;
29 while(merge != n - 1)
30 {
31 for(int i = 1;i <= m;i ++)
32 {
33 if(use_edge[i]) continue;
34 int x = find(s[i]),y = find(t[i]);
35 if(x == y) continue;
36 if(better(i,best[x])) best[x] = i;
37 if(better(i,best[y])) best[y] = i;
38 }
39 for(int i = 1;i <= n;i ++)
40 {
41 if(best[i]){
42 int x = find(s[best[i]]),y = find(t[best[i]]);
43 if(x != y){
44 use_edge[best[i]] = 1;
45 f[x] = y;
46 merge ++;
47 sum += w[best[i]];
48 }
49 best[i] = 0;
50 }
51 }
52 }
53 return sum;
54 }
55 }g;
56 int main(void)
57 {
58 ios::sync_with_stdio(false);
59 cin >> n >> m;
60 for(int i = 1;i <= m;i ++) cin >> s[i] >> t[i] >> w[i];
61 g.init();
62 cout << g.get() << '\n';
63 return 0;
64 }
很经典的题,题目大意为:
给定一个n个节点的完全图,每个节点有个编号ai,节点i和节点j之间边的权值为ai xor aj,求该图的最小生成树的权值和。
完全图,优先考虑Borůvka
需要在n log n左右的时间中求出每个连通块最小的连接的边,在这道题中边权可以通过点权求出
但是,这是不能直接算出每条边的边权的,因为这一看就是会超时的
所以根据二进制的性质,考虑建对全局建一个01trie,然后再给每一个连通块建一个tire,Borůvka算法每一次合并两个连通块,就合并两个tire,再在trie上维护子树的size,点权异或最小值就直接在全局trie与当前连通块的size作差得到树上贪心即可
总共会迭代log n次,总时间复杂度为O(n logn logsize ),空间复杂度为O(n log size)
code,仅供参考,没有注释
1 #include"bits/stdc++.h"
2 #define ll long long
3 #define inl inline
4 #define reg register
5 #define ls ch[now][0]
6 #define rs ch[now][1]
7 using namespace std;
8 const int N = 2e5 + 10;
9 const int inf = 0x7ffffff;
10
11 int L[N * 40],R[N * 40];
12 int ch[N * 40][2];
13 int tot;
14 int n,a[N],root;
15 inl int read(void)
16 {
17 int x = 0,f = 1;char ch = getchar();
18 while(!isdigit(ch)) f = ch == '-' ? - 1 : f,ch = getchar();
19 while(isdigit(ch)) x = (x << 3) + (x << 1) + ch - '0',ch = getchar();
20 return x * f;
21 }
22 inl void Insert(int &now,int x,int dep)
23 {
24 if(!now) now = ++ tot;
25 L[now] = min(L[now],x),R[now] = max(R[now],x);
26 if(dep < 0) return;
27 int bit = a[x] >> dep & 1;
28 Insert(ch[now][bit],x,dep - 1);
29 }
30 inl int query(int now,int val,int dep)
31 {
32 if(dep < 0) return 0;
33 int bit = val >> dep & 1;
34 if(ch[now][bit]) return query(ch[now][bit],val,dep - 1);
35 else return query(ch[now][bit ^ 1],val,dep - 1) + (1 << dep);
36 }
37 inl ll dfs(int now,int dep)
38 {
39 if(dep < 0) return 0;
40 if(R[ls] && R[rs])
41 {
42 int minn = inf;
43 for(int i = L[ls];i <= R[ls];i ++) minn = min(minn,query(rs,a[i],dep - 1));
44 return dfs(ls,dep - 1) + dfs(rs,dep - 1)+ minn + (1 << dep);
45 }
46 if(R[ls]) return dfs(ls,dep - 1);
47 if(R[rs]) return dfs(rs,dep - 1);
48 return 0;
49 }
50 int main(void)
51 {
52 n = read();
53 for(int i = 1;i <= n;i ++) a[i] = read();
54 sort(a + 1,a + 1 + n);
55 memset(L,0x3f,sizeof(L));
56 for(int i = 1;i <= n;i ++) Insert(root,i,30);
57 printf("%lld\n",dfs(root,30));
58 return 0;
59 }
Borůvka MST算法的更多相关文章
- Borůvka (Sollin) 算法求 MST 最小生成树
基本思路: 用定点数组记录每个子树的最近邻居. 对于每一条边进行处理: 如果这条边连成的两个顶点同属于一个集合,则不处理,否则检测这条边连接的两个子树,如果是连接这两个子树的最小边,则更新 (合并). ...
- Codeforces.888G.Xor-MST(Borůvka算法求MST 贪心 Trie)
题目链接 \(Description\) 有一张\(n\)个点的完全图,每个点的权值为\(a_i\),两个点之间的边权为\(a_i\ xor\ a_j\).求该图的最小生成树. \(n\leq2*10 ...
- 【做题】CSA72G - MST and Rectangles——Borůvka&线段树
原文链接 https://www.cnblogs.com/cly-none/p/CSA72G.html 题意:有一个\(n \times n\)的矩阵\(A\),\(m\)次操作,每次在\(A\)上三 ...
- 最小生成树-Borůvka算法
一般求最小生成树的时候,最流行的是Kruskal算法,一种基于拟阵证明的贪心,通过给边排序再扫描一次边集,利用并查集优化得到,复杂度为\(O(ElogE)\).另一种用得比较少的是Prim算法,利用优 ...
- Kruskal vs Borůvka
做了个对比.Borůvka算法对于稠密图效果特别好.这两个都是求生成森林的算法.Prim+heap+tarjan过于难写不写了. V=200,E=1000 Kruskal method 4875048 ...
- Borůvka algorithm
Borůvka algorithm 我好无聊啊,直接把wiki的算法介绍翻译一下把. wiki关于Borůvka algorithm的链接:链接 Borůvka algorithm是一个在所有边权都是 ...
- 最小生成树MST算法(Prim、Kruskal)
最小生成树MST(Minimum Spanning Tree) (1)概念 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边,所谓一个 ...
- NOIp 图论算法专题总结 (1):最短路、最小生成树、最近公共祖先
系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 最短路 Floyd 基本思路:枚举所有点与点的中点,如果从中点走最短,更新两点间 ...
- 「CSA72」MST
「CSA72」MST 题目大意:有一个大小为 \(n\) 的无向完全图,\(x, y\) 之间的边权值为 \(a[\min(x,y)][\max(x,y)]\) ,初始为0,进行 \(m\) 次修改, ...
- 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind
最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...
随机推荐
- Java | zuul 1.x 是如何实现请求转发的
zuul 1.x 是如何实现请求转发的 文档写的再好,也不如源码写的好 源码地址: GitHub: https://github.com/Netflix/zuul Gitee: https://git ...
- DES算法揭秘:数据加密的前沿技术
DES算法起源: DES(Data Encryption Standard)算法是一种对称密钥加密算法,由IBM的Horst Feistel设计,于1977年被美国国家标准局(NBS)确定为数据加密标 ...
- 基于webpack与TypeScript的SolidJS项目搭建
本文将讲述如何基于webpack与TypeScript搭建一个基础的支持less模块的solidjs项目.方便后续涉及到solidjs相关分析与讨论都可以基于本文的成果之上进行. 前置 nodejs ...
- 3DCAT实时云渲染助力上海市乡村振兴可视化平台,展现数字乡村的魅力
乡村振兴是党的十九大提出的重大战略,是实现中华民族伟大复兴的重要基础.上海作为超大城市,如何推进乡村振兴,让乡村成为城市发展的重要支撑和生态屏障,是一项重大课题. 为了全面展示上海市乡村振兴的成果和规 ...
- 瑞云科技荣获全国电子信息行业专精特新“最具创新价值 TOP20”!
"专精特新",从概念提出到写入政府工作报告走过了十年.这十年来我国促进中小企业发展力度之大.出台政策之密集.含金量之高前所未有,足见走专精特新发展之路深入人心."专精特新 ...
- 改Bug的经验
如果修复某个Bug花了很长时间,这时候就要问问自己为什么,怎么做才吸取经验教训,在类似的问题上不再出问题,以及采用的方法,使用的工具是否还有改进的地方: 当所有问题都解决之后,一定要梳理下从最初找Bu ...
- KinbaseES 优化之IO优化
IO 资源作为目前服务器中最昂贵的资源之一,是目前绝大部分业务系统主要的瓶颈资源,原因就在于服务器相关的硬件资源中IO资源的性能提升是难度最大的.存储的发展步伐远低于内存和CPU的发展. 在数据库管理 ...
- KingbaseES V8R6 集群运维系列--archive_cleanup_command参数应用
案例说明: 参数archive_cleanup_command可以配置在kingbase.conf文件中,用于备库清理不在需要的归档日志,参数详细说明见下图: https://postgresql ...
- .NET分布式Orleans - 8 - 贪吃蛇项目实战(准备阶段)
到目前为止,Orleans7的核心概念基本已经学完,我准备使用Orleans7做一个项目实战,来总结自己的学习效果. 项目效果 通过Orleans7来完成一个贪吃蛇游戏,要求如下: 可以多人在线玩 贪 ...
- debootstrap 命令行安装 debian12(stable) btrfs文件系统 uefi引导 (像arch一样)
1,制作debian12 live 启动盘 2.联网,可以手机usb共享,可以用wpasupplicant连wifi 3.修改镜像列表 sudo nano /etc/apt/source.list 修 ...