Borůvka algorithm

我好无聊啊,直接把wiki的算法介绍翻译一下把。

wiki关于Borůvka algorithm的链接:链接

Borůvka algorithm是一个在所有边权都是不同的图中找到最小生成树的贪心算法。(其实边权相同也可以做,具体见后文),或者在一个不联通的图找到最小生成树。

它由 Otakar Borůvka (人名)第一次发表在1926年,被作为给Moravia(一个地区)一种有效的电网建设方法。这个算法被Choquet在1938年重新发现,在1951年,它又被 Florek, Łukasiewicz, Perkal, Steinhaus, and Zubrzyck重新发现。又在1965年被Georges Sollin发现。这个算法经常被叫做Sollin's algorithm.特别在 parallel computing的文献中。

算法过程:

一开始每个点自成一个联通块。

每次所有联通块都找一条边权最小的边,其中一端在该联通块内而另一端不在,接下来加入这些边并合并联通块。

重复上述操作直到没有联通块可以合并。

一个细节:由于我们的写法问题,在边权相同的特殊情况下,我们会连接形成环,所以我们增加一个维度来排序。

看一下这东西流程:

可以用切割性质证明算法的正确性。

切割性质:

将点集V分成S和V-S,一端在S内另一端在V-S内边权最小的边,一定出现在最小生成树中。

复杂度分析:

显然,联通块们,每次最小减少至原来的一般,每一次都要遍历每一条边,所以复杂度:\(O(Elog_V)\)

$$\color{white}{\text{完美结束,顺带试验一下透明字体}}$$

参考资料:

脑子

wiki

Tweetuzki

题目们

P3366 【模板】最小生成树

CF888G

UOJ 240

模板题的代码:

  1. /*header*/
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <algorithm>
  6. #include <queue>
  7. #include <vector>
  8. #include <cmath>
  9. #define rep(i , x, p) for(int i = x;i <= p;++ i)
  10. #define sep(i , x, p) for(int i = x;i >= p;-- i)
  11. #define gc getchar()
  12. #define pc putchar
  13. #define ll long long
  14. #define mk make_pair
  15. #define fi first
  16. #define se second
  17. using std::min;
  18. using std::max;
  19. using std::swap;
  20. const int inf = 0x3f3f3f3f;
  21. const int maxN = 5000 + 7;
  22. const int maxM = 200000 + 7;
  23. inline int gi() {
  24. int x = 0,f = 1;char c = gc;
  25. while(c < '0' || c > '9') {if(c == '-')f = -1;c = gc;}
  26. while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = gc;}return x * f;
  27. }
  28. struct Node {
  29. int u , v, w;
  30. }Map[maxM];
  31. int n , m;
  32. int f[maxN];
  33. bool vis[maxM];//该边是否用过
  34. int d[maxN] , a[maxN];//各子树的最小连外边的权值
  35. int id[maxN];// 记录各子树的最小连外边的编号
  36. int find(int x) {return f[x] == x ? x : f[x] = find(f[x]);}
  37. int unqie(int x , int y) {f[find(x)] = find(y);}
  38. int Boruvka() {
  39. for(int i = 1;i <= n;++ i) f[i] = i;
  40. int sum = 0;
  41. while(true) {
  42. bool flag = false;
  43. for(int i = 1;i <= n;++ i) d[i] = inf;
  44. for(int i = 1;i <= m;++ i) {
  45. int u = find(Map[i].u) , v = find(Map[i].v), c = a[u] & a[v];
  46. if(u == v) continue;
  47. flag = true;
  48. if(c < d[u] || (d[u] == c && id[u] > i)) id[u] = i , d[u] = c;
  49. if(c < d[v] || (d[v] == c && id[v] > i)) id[v] = i , d[v] = c;
  50. }
  51. if(!flag) break;
  52. for(int i = 1;i <= n;++ i) {
  53. if(d[i] != inf && !vis[id[i]]) {
  54. unqie(Map[id[i]].u , Map[id[i]].v);
  55. sum += Map[id[i]].w;
  56. vis[id[i]] = true;
  57. }
  58. }
  59. }
  60. int tot = 0;
  61. for(int i = 1;i <= n;++ i) if(f[i] == i) tot ++;
  62. tot > 1 ? printf("orz") : printf("%d",sum);
  63. }
  64. int main() {
  65. n = gi();m = gi();
  66. for(int i = 1;i <= m;++ i) {
  67. int u = gi() , v = gi(), w = gi();
  68. Map[i] = (Node) {u , v, w};
  69. }
  70. Boruvka();
  71. return 0;
  72. }

CF888G

建造Trie,合并Trie树。

Borůvka algorithm的更多相关文章

  1. Kruskal vs Borůvka

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

  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. Borůvka (Sollin) 算法求 MST 最小生成树

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

  6. bzoj2429- 聪明的猴子

    题意其实就是说有很多个点,求一组边把它们都连接起来,并且最大的那条边最小.很明显这就是一个最小生成树,是一颗保证最长边最短的树. 代码 刚刚学了个Borůvka算法,于是写了两个. Borůvka # ...

  7. 「CSA72」MST

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

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

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

  9. MD5 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)

    MD5 编辑 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护.该算法的文件号为RFC 1321( ...

随机推荐

  1. APP网站安全漏洞检测服务的详细介绍

    01)概述: 关于APP漏洞检测,分为两个层面的安全检测,包括手机应用层,以及APP代码层,与网站的漏洞检测基本上差不多,目前越来越多的手机应用都存在着漏洞,关于如何对APP进行漏洞检测,我们详细的介 ...

  2. Vue 入门之目录结构介绍

    Vue 是一套用于构建用户界面的渐进式框架,与其它大型的页面框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合.另一方面,当 ...

  3. Kafka单节点及集群配置安装

    一.单节点 1.上传Kafka安装包到Linux系统[当前为Centos7]. 2.解压,配置conf/server.property. 2.1配置broker.id 2.2配置log.dirs 2. ...

  4. .net core下Redis帮助类

      0.引入.net core环境下Redis的NuGet包,StackExchange.Redis,现目前最新的2.0.519. 帮助类Code: using System; using Syste ...

  5. 关于Java 中跳出多重循环

    前言 环境:window10 JDK 1.8 应用场景:在多个for循环或while循环中,直接跳到最外层的循环外面,而不是需要层层退出来. 使用: 使用一个标签label(也可以是其他单词,不能是关 ...

  6. SQL Server系统表sysobjects介绍

    SQL Server系统表sysobjects介绍 sysobjects 表结构: 列名 数据类型 描述 name sysname 对象名,常用列 id int 对象标识号 xtype char(2) ...

  7. RubyGems系列之创建自己的gem

    转载请注明来源:https://www.cnblogs.com/zhanggui/p/9720818.html 一. 前言 我们可以在rubygems.org中下载安装他人创建的gem.现在,我们尝试 ...

  8. Tomcat调试404错误

    开篇附上我找到的部分解决方法摘自:https://blog.csdn.net/psp0001060/article/details/51879232 如不想跳转查看,链接内容如下: 问题一:      ...

  9. 基本MVVM 和 ICommand用法举例(转)

    引言 在本贴中,我们将学习WPF Commands. Commands 可以很好地与 MVVM 模式 (Model- View-ViewModel)结合在一起.我们也将看到,视图(view)实际上是怎 ...

  10. JAVA进阶23

    1.统计文件夹大小 package cn.demo02; import java.io.File; /** * @Classname DirTest03 * @Description TODO * @ ...