当我认为最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 }

luogu CF888G XOR-MST

很经典的题,题目大意为:

给定一个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算法的更多相关文章

  1. Borůvka (Sollin) 算法求 MST 最小生成树

    基本思路: 用定点数组记录每个子树的最近邻居. 对于每一条边进行处理: 如果这条边连成的两个顶点同属于一个集合,则不处理,否则检测这条边连接的两个子树,如果是连接这两个子树的最小边,则更新 (合并). ...

  2. Codeforces.888G.Xor-MST(Borůvka算法求MST 贪心 Trie)

    题目链接 \(Description\) 有一张\(n\)个点的完全图,每个点的权值为\(a_i\),两个点之间的边权为\(a_i\ xor\ a_j\).求该图的最小生成树. \(n\leq2*10 ...

  3. 【做题】CSA72G - MST and Rectangles——Borůvka&线段树

    原文链接 https://www.cnblogs.com/cly-none/p/CSA72G.html 题意:有一个\(n \times n\)的矩阵\(A\),\(m\)次操作,每次在\(A\)上三 ...

  4. 最小生成树-Borůvka算法

    一般求最小生成树的时候,最流行的是Kruskal算法,一种基于拟阵证明的贪心,通过给边排序再扫描一次边集,利用并查集优化得到,复杂度为\(O(ElogE)\).另一种用得比较少的是Prim算法,利用优 ...

  5. Kruskal vs Borůvka

    做了个对比.Borůvka算法对于稠密图效果特别好.这两个都是求生成森林的算法.Prim+heap+tarjan过于难写不写了. V=200,E=1000 Kruskal method 4875048 ...

  6. Borůvka algorithm

    Borůvka algorithm 我好无聊啊,直接把wiki的算法介绍翻译一下把. wiki关于Borůvka algorithm的链接:链接 Borůvka algorithm是一个在所有边权都是 ...

  7. 最小生成树MST算法(Prim、Kruskal)

    最小生成树MST(Minimum Spanning Tree) (1)概念 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边,所谓一个 ...

  8. NOIp 图论算法专题总结 (1):最短路、最小生成树、最近公共祖先

    系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 最短路 Floyd 基本思路:枚举所有点与点的中点,如果从中点走最短,更新两点间 ...

  9. 「CSA72」MST

    「CSA72」MST 题目大意:有一个大小为 \(n\) 的无向完全图,\(x, y\) 之间的边权值为 \(a[\min(x,y)][\max(x,y)]\) ,初始为0,进行 \(m\) 次修改, ...

  10. 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind

    最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...

随机推荐

  1. leetcode数据库sql之Rising Temperature

    leetcode原文引用: Given a Weather table, write a SQL query to find all dates' Ids with higher temperatur ...

  2. springboot如何优雅的获取前端参数

    写在前面 对于初学者来说,困难的不是理论知识,而是如何在程序中具体实现. 现在的项目基本上都是前后端分离的项目,如何打通前后端,接收前端传过来的参数呢? 废话不多说,这篇文章就来说一说接收前端参数的具 ...

  3. Java valueOf() 方法---->摘抄

    valueOf(boolean b): 返回 boolean 参数的字符串表示形式.. valueOf(char c): 返回 char 参数的字符串表示形式. valueOf(char[] data ...

  4. java的对象内存和数据类型

    一.三种情况的对象内存图 (1)Java内存分配介绍: 栈: 队: 方法区(jdk7):加载字节码文件.(从jdk8开始取消方法区,新增元空间,把原来方法区的多种功能进行拆分,有的功能放到堆中,有的功 ...

  5. 记录--静态网站 H5 跳小程序,以及踩坑

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 背景 我司有智慧功成家APP和对应的小程序,现在已经实现APP分享到微信,微信点击分享链接直接进入小程序. 目前有一个问题就是我们APP在 ...

  6. 记录--Vue中如何导出excel表格

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.导出静态数据 1.安装 vue-json-excel npm i vue-json-excel 注意,此插件对node有版本要求,安装 ...

  7. 移动端弹性布局方案lib-flexible实践

    2个月前,写过一篇文章<从网易与淘宝的font-size思考前端设计稿与工作流>总结过一些移动web中有关手机适配的一些思路,当时也是因为工作的关系分析了下网易跟淘宝的移动页面,最后才有那 ...

  8. java读写txt

    /** * 传入txt路径读取txt文件 * * @param txtPath * @return 返回读取到的内容 */ public String readTxt(String txtPath) ...

  9. 【OpenCV】OpenCV (C++) 与 OpenCvSharp (C#) 之间数据通信

      OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux.Windows.Android和Mac OS操作系统上. 它轻量级而且高效--由一 ...

  10. Fastjson反序列化分析

    依赖 先研究1.2.24版本的,版本高了就有waf了,不过也能绕,高版本以后再说 <dependency> <groupId>com.alibaba</groupId&g ...