Borůvka algorithm
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{完美结束,顺带试验一下透明字体}}$$
参考资料:
题目们
P3366 【模板】最小生成树
CF888G
UOJ 240
模板题的代码:
/*header*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#define rep(i , x, p) for(int i = x;i <= p;++ i)
#define sep(i , x, p) for(int i = x;i >= p;-- i)
#define gc getchar()
#define pc putchar
#define ll long long
#define mk make_pair
#define fi first
#define se second
using std::min;
using std::max;
using std::swap;
const int inf = 0x3f3f3f3f;
const int maxN = 5000 + 7;
const int maxM = 200000 + 7;
inline int gi() {
int x = 0,f = 1;char c = gc;
while(c < '0' || c > '9') {if(c == '-')f = -1;c = gc;}
while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = gc;}return x * f;
}
struct Node {
int u , v, w;
}Map[maxM];
int n , m;
int f[maxN];
bool vis[maxM];//该边是否用过
int d[maxN] , a[maxN];//各子树的最小连外边的权值
int id[maxN];// 记录各子树的最小连外边的编号
int find(int x) {return f[x] == x ? x : f[x] = find(f[x]);}
int unqie(int x , int y) {f[find(x)] = find(y);}
int Boruvka() {
for(int i = 1;i <= n;++ i) f[i] = i;
int sum = 0;
while(true) {
bool flag = false;
for(int i = 1;i <= n;++ i) d[i] = inf;
for(int i = 1;i <= m;++ i) {
int u = find(Map[i].u) , v = find(Map[i].v), c = a[u] & a[v];
if(u == v) continue;
flag = true;
if(c < d[u] || (d[u] == c && id[u] > i)) id[u] = i , d[u] = c;
if(c < d[v] || (d[v] == c && id[v] > i)) id[v] = i , d[v] = c;
}
if(!flag) break;
for(int i = 1;i <= n;++ i) {
if(d[i] != inf && !vis[id[i]]) {
unqie(Map[id[i]].u , Map[id[i]].v);
sum += Map[id[i]].w;
vis[id[i]] = true;
}
}
}
int tot = 0;
for(int i = 1;i <= n;++ i) if(f[i] == i) tot ++;
tot > 1 ? printf("orz") : printf("%d",sum);
}
int main() {
n = gi();m = gi();
for(int i = 1;i <= m;++ i) {
int u = gi() , v = gi(), w = gi();
Map[i] = (Node) {u , v, w};
}
Boruvka();
return 0;
}
CF888G
建造Trie,合并Trie树。
Borůvka algorithm的更多相关文章
- Kruskal vs Borůvka
做了个对比.Borůvka算法对于稠密图效果特别好.这两个都是求生成森林的算法.Prim+heap+tarjan过于难写不写了. V=200,E=1000 Kruskal method 4875048 ...
- 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算法,利用优 ...
- Borůvka (Sollin) 算法求 MST 最小生成树
基本思路: 用定点数组记录每个子树的最近邻居. 对于每一条边进行处理: 如果这条边连成的两个顶点同属于一个集合,则不处理,否则检测这条边连接的两个子树,如果是连接这两个子树的最小边,则更新 (合并). ...
- bzoj2429- 聪明的猴子
题意其实就是说有很多个点,求一组边把它们都连接起来,并且最大的那条边最小.很明显这就是一个最小生成树,是一颗保证最长边最短的树. 代码 刚刚学了个Borůvka算法,于是写了两个. Borůvka # ...
- 「CSA72」MST
「CSA72」MST 题目大意:有一个大小为 \(n\) 的无向完全图,\(x, y\) 之间的边权值为 \(a[\min(x,y)][\max(x,y)]\) ,初始为0,进行 \(m\) 次修改, ...
- NOIp 图论算法专题总结 (1):最短路、最小生成树、最近公共祖先
系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 最短路 Floyd 基本思路:枚举所有点与点的中点,如果从中点走最短,更新两点间 ...
- MD5 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)
MD5 编辑 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护.该算法的文件号为RFC 1321( ...
随机推荐
- vmware完整克隆(linux)
vmware中的完整克隆是基于指定的虚拟机克隆出相同的一份出来,不必再安装 但是我们要保证三个地方不能一样,一个是主机名称(hostname),一个是虚拟网卡设备mac地址,还有一个是ip地址 所以我 ...
- 一起学Android之GridView
本文以一个简单的小例子,简述Android开发中GridView的常见应用,仅供学习分享使用. 概述 GiridView是一个表格显示资源的控件,可以在两个可滚动的方向上显示.列表项的资源会通过Lis ...
- Android Studio教程01-的工程和目录结构解析
目录 1.主目录 1.1. app目录 1.2.项目资源文件夹res 2. 理解build.gradle文件 2.1. 外部build.gradle 2.2. app文件下的build.gradle ...
- TextSwitcher 文本切换器的功能与用法
TextSwitcher集成了ViewSwitcher, 因此它具有与ViewSwitcher相同的特性:可以在切换View组件时使用动画效果.与ImageSwitcher相似的是,使用TextSwi ...
- DVWA 黑客攻防演练(十三)JS 攻击 JavaScript Attacks
新版本的 DVWA 有新东西,其中一个就是这个 JavaScript 模块了. 玩法也挺特别的,如果你能提交 success 这个词,成功是算你赢了.也看得我有点懵逼. 初级 如果你改成 " ...
- 996.ICU 写给... 写给年轻的自己
好久不"水"长文了,随着Github开源项目996.ICU (工作996,生病ICU) (本意是为了指出互联网等早9晚9每周工作6天的不良加班工作制风气不符合法律,是对程序员等技术 ...
- shell脚本-正则、grep、sed、awk
----------------------------------------正则---------------------------------------- 基础正则 ^word ##搜索以w ...
- 【spring源码分析】IOC容器初始化(四)
前言:在[spring源码分析]IOC容器初始化(三)中已经分析了BeanDefinition注册之前的一些准备工作,下面将进入BeanDefinition注册的核心流程. //DefaultBean ...
- .NET core2.0 发布至IIS中
.NET CORE和asp.net 发布时不太一样,ASP.NET Core不再是由IIS工作进程(w3wp.exe)托管,而是使用自托管Web服务器(Kestrel)运行,IIS则是作为反向代理的角 ...
- Luogu4655 [CEOI2017]Building Bridges
Luogu4655 [CEOI2017]Building Bridges 有 \(n\) 根柱子依次排列,每根柱子都有一个高度.第 \(i\) 根柱子的高度为 \(h_i\) . 现在想要建造若干座桥 ...