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( ...
随机推荐
- [目录]C#学习笔记
C#是微软.NET平台下最重要的编程语言,它与C.C++不同,C#编写的源程序是托管在.NET平台下的.C#源程序经C#编译器编译成中间语言(IL,Intermediate Language),再经C ...
- python 验证码识别库pytesseract的使用
笔者环境 centos7 python3 pytesseract只是tesseract-ocr的一种实现接口.所以要先安装tesseract-ocr(大名鼎鼎的开源的OCR识别引擎). 依赖安装 yu ...
- SHA1withRSA加签名和验签名
利用私钥加签名: //contentForSign为需加标签的字符串 public String signWhithsha1withrsa(string contentForSign) { strin ...
- js坚持不懈之17:onmousedown、onmouseup 以及 onclick 事件
<!DOCTYPE html> <html> <body> <div onmouseover = "mOver(this)" onmous ...
- RocketMQ从3.5.8升级到4.3.2版本实战记录
背景 我们在很早之前大约在2015年8月份左右我们开始使用Rocketmq作为公司消息中间件,那个时候RocketMQ还没有捐赠给Acaphe. RocketMQ版本还是3.2.6,中间升级了一次版本 ...
- android申请多个权限的正确姿势
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permi ...
- 【spring源码分析】IOC容器初始化(二)
前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...
- 添加python虚拟环境
在我centos上装有两个python版本 # 我在~/py3/目录下创建虚拟环境,该目录为python3的一个独立环境 [root@localhost /]# cd home [root@local ...
- Mysql 创建事件任务
DELIMITER $$ CREATE DEFINER=`root`@`%` EVENT `test` ON SCHEDULE EVERY 1 DAY STARTS '2019-02-12 00:00 ...
- 宝塔服务器面板 部署 thinkphp5 坑
thinkphp5 在宝塔服务器上部署,出现的问题: 1. File not found. 原因: 宝塔服务器默认不支持 pathinfo 的路径访问:需要在软件 - PHP - 管理里面,安装php ...