Kruskal vs Borůvka
做了个对比.Borůvka算法对于稠密图效果特别好.这两个都是求生成森林的算法.Prim+heap+tarjan过于难写不写了.
V=200,E=1000
Kruskal method
487504811
Time usage: 129 us
Bor(uc)uvka method
487504811
Time usage: 94 us
V=500,E=3000
Kruskal method
1068863143
Time usage: 431 us
Bor(uc)uvka method
1068863143
Time usage: 321 us
V=1000,E=10000
Kruskal method
1248132507
Time usage: 1626 us
Bor(uc)uvka method
1248132507
Time usage: 707 us
V=2000,E=50000
Kruskal method
1023451601
Time usage: 4444 us
Bor(uc)uvka method
1023451601
Time usage: 1781 us
V=5000,E=100000
Kruskal method
3177798955
Time usage: 8300 us
Bor(uc)uvka method
3177798955
Time usage: 3473 us
V=10000,E=300000
Kruskal method
4240792222
Time usage: 26751 us
Bor(uc)uvka method
4240792222
Time usage: 11332 us
V=10000,E=500000
Kruskal method
2548867302
Time usage: 45754 us
Bor(uc)uvka method
2548867302
Time usage: 18561 us
V=20000,E=1000000
Kruskal method
5166175346
Time usage: 92360 us
Bor(uc)uvka method
5166175346
Time usage: 38672 us
V=50000,E=1000000
Kruskal method
32391070642
Time usage: 96633 us
Bor(uc)uvka method
32391070642
Time usage: 54670 us
V=100000,E=1000000
Kruskal method
129350661440
Time usage: 101094 us
Bor(uc)uvka method
129350661440
Time usage: 79034 us
V=300000,E=2000000
Kruskal method
578989469565
Time usage: 229092 us
Bor(uc)uvka method
578989469565
Time usage: 208983 us
V=500000,E=6000000
Kruskal method
536707083899
Time usage: 689042 us
Bor(uc)uvka method
536707083899
Time usage: 654468 us
V=1000000,E=10000000
Kruskal method
1290266237257
Time usage: 1254349 us
Bor(uc)uvka method
1290266237257
Time usage: 1443208 us
V=5000000,E=50000000
Kruskal method
6456472043049
Time usage: 8274752 us
Bor(uc)uvka method
6456472043049
Time usage: 16565600 us
V=10000000,E=50000000
Kruskal method
25804619307783
Time usage: 10263962 us
Bor(uc)uvka method
25804619307783
Time usage: 18875336 us
这个Boruvka的写法不是最好的;但是链表动态删除的Boruvka会很长也就没有比较的意义了.
#define sizex 100000000
#include <cmath>
#include <cstdio>
#include <random>
#include <algorithm>
#include <malloc.h>
#include <sys/time.h>
using namespace std;
int *data,res;
long long mytic(){
long long result = 0.0;
struct timeval tv;
gettimeofday( &tv, NULL );
result = ((long long)tv.tv_sec)*1000000 + (long long)tv.tv_usec;
return result;
}
#define dic1() disA(generator)
#define dic2() disB(generator)
struct edge{int a,b,w;};
bool cmp(edge a,edge b){
return a.w<b.w;
}
#define foredge for(int i=0;i<gr.El;++i)
#define forvert2 for(int i=0;i<gr.N;++i)
#define eg gr.E[i]
struct graph{
int N,El;
edge E[50000000];
void sorter(){
sort(E,E+El,cmp);
}
void genData(int a,int b){
N=a;
El=b;
mt19937 generator;
uniform_int_distribution<int> disA(0,N-1);
uniform_int_distribution<int> disB(0,21474836);
for(int i=0;i<El;++i){
E[i].a=dic1();
while((E[i].b=dic1())==E[i].a);
E[i].w=dic2();
}
}
} gr;
struct ds_set{
int fa[10000000];
void clear(){
for(int i=0;i<gr.N;++i) fa[i]=-1;
}
int find(int p){return ~fa[p]?fa[p]=find(fa[p]):p;}
inline int merge(int a,int b){return (a==b)?(-1):(fa[b]=a);}
} ds;
#define ffind(a) ds.find(a)
#define funion(a,b) ds.merge(a,b)
struct algo_Kruskal{
long long run(){
long long ans=0;
gr.sorter();
int a,b;
foredge{
a=ffind(eg.a),b=ffind(eg.b);
ans+=~funion(a,b)?eg.w:0;
}
return ans;
}
} Kruskal;
struct algo_Boruvka{
struct v{
int a,p;
} vm[10000000];
long long run(){
long long ans=0;
int a,b,c,w;
while(1){
c=0;
forvert2 vm[i].a=100000000;
foredge{
w=eg.w,a=ffind(eg.a),b=ffind(eg.b);
if(a==b) continue;
++c;
if(w<vm[a].a) vm[a]={w,i};
if(w<vm[b].a) vm[b]={w,i};
}
if(!c) break;
forvert2 if(vm[i].a!=100000000) {
a=ffind(gr.E[vm[i].p].a);
vm[i].p=ffind(gr.E[vm[i].p].b);
ans+=(~funion(a,vm[i].p))?vm[i].a:0;
}
}
return ans;
}
} Boruvka;
FILE* loggar;
void testN(){
long long i;
printf("Kruskal method\n");
fprintf(loggar,"Kruskal method\n");
ds.clear();
long long start=mytic();
i=Kruskal.run();
start=mytic()-start;
printf("%lld\n",i);
printf("Time usage: %lld us\n",start);
fprintf(loggar,"%lld\n",i);
fprintf(loggar,"Time usage: %lld us\n",start);
}
void testU(){
long long i;
printf("Bor(uc)uvka method\n");
fprintf(loggar,"Bor(uc)uvka method\n");
ds.clear();
long long start=mytic();
i=Boruvka.run();
start=mytic()-start;
printf("%lld\n",i);
printf("Time usage: %lld us\n",start);
fprintf(loggar,"%lld\n",i);
fprintf(loggar,"Time usage: %lld us\n",start);
}
int as[15]={200 ,500 ,1000 ,2000 ,5000 ,10000 ,10000 ,20000 ,50000 ,100000 ,300000 ,500000 ,1000000 ,5000000 ,10000000};
int bs[15]={1000,3000,10000,50000,100000,300000,500000,1000000,1000000,1000000,2000000,6000000,10000000,50000000,50000000};
int main(){
int a,b,c,i,j,k,l,m,n,N,U,P,UP;
loggar=fopen("MSTTest.data","w");
for(int i=0;i<15;++i){
printf("%d %d\n",as[i],bs[i]);
fprintf(loggar,"V=%d,E=%d\n",as[i],bs[i]);
gr.genData(as[i],bs[i]);
testN(),testU();
}
fclose(loggar);
return 0;
}
过饱和稠密图上花样虐Kruskal
V=3000,E=50000000
Kruskal method
2305771
Time usage: 5808210 us
Bor(uc)uvka method
2305771
Time usage: 1270494 us
V=5000,E=50000000
Kruskal method
6381189
Time usage: 5789551 us
Bor(uc)uvka method
6381189
Time usage: 1274763 us
V=10000,E=50000000
Kruskal method
25291282
Time usage: 5834369 us
Bor(uc)uvka method
25291282
Time usage: 1654772 us
稀疏图大概比Kruskal慢一倍,花样虐Prim.
还有一个小花絮就是我弄错随机数生成范围Kruskal狂错不止.
Prim+pbdsheap还是有前途的,不过Boruvka完全够了.
两个长度加起来和不带堆的Prim一样了真不错.
Kruskal vs Borůvka的更多相关文章
- 【做题】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 algorithm
Borůvka algorithm 我好无聊啊,直接把wiki的算法介绍翻译一下把. wiki关于Borůvka algorithm的链接:链接 Borůvka algorithm是一个在所有边权都是 ...
- Codeforces.888G.Xor-MST(Borůvka算法求MST 贪心 Trie)
题目链接 \(Description\) 有一张\(n\)个点的完全图,每个点的权值为\(a_i\),两个点之间的边权为\(a_i\ xor\ a_j\).求该图的最小生成树. \(n\leq2*10 ...
- Borůvka (Sollin) 算法求 MST 最小生成树
基本思路: 用定点数组记录每个子树的最近邻居. 对于每一条边进行处理: 如果这条边连成的两个顶点同属于一个集合,则不处理,否则检测这条边连接的两个子树,如果是连接这两个子树的最小边,则更新 (合并). ...
- bzoj2429- 聪明的猴子
题意其实就是说有很多个点,求一组边把它们都连接起来,并且最大的那条边最小.很明显这就是一个最小生成树,是一颗保证最长边最短的树. 代码 刚刚学了个Borůvka算法,于是写了两个. Borůvka # ...
- 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\) 次修改, ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
随机推荐
- WCF 入门(23,24)
前言 重新找了工作,过去的事情就过去好了.有些不一样的经历也不是说一定就是坏事. 第24集 在控制台应用程序中自托管WCF服务 Self hosting a wcf service in consol ...
- 第二十八课:focusin与focusout,submit,oninput事件的修复
focusin与focusout 这两个事件是IE的私有实现,能冒泡,它代表获得焦点或失去焦点的事件.现在只有Firefox不支持focusin,focusout事件.其实另外两个事件focus和bl ...
- [设计模式] javascript 之 适配器模式
适配器模式说明 说明: 适配器模式,一般是为要使用的接口,不符本应用或本系统使用,而需引入的中间适配层类或对象的情况: 场景: 就好比我们买了台手机,买回来后发现,充电线插头是三插头,但家里,只有两插 ...
- 关于js的string的3个函数slice,substring,substr对比
slice,substring,substr三个函数都是截取字符串,但是对参数的处理有区别 参数处理相似的两个函数式slice和substring slice(start,end)和substring ...
- 视频播放用户行为记录之使用Cache的方法
在上一篇文章http://www.cnblogs.com/ryuasuka/p/3483632.html中,为了获取视频播放时的用户行为,并且要异步地将其写入XML文件中,我采用了先写入log,后生成 ...
- Vijos p1770 大内密探 树形DP+计数
4天终于做出来了,没错我就是这么蒟蒻.教训还是很多的. 建议大家以后编树形DP不要用记忆化搜索,回溯转移状态个人感觉更有条理性. 大神题解传送门 by iwtwiioi 我的题解大家可以看注释&quo ...
- 利用Spring中的HtmlUtils.htmlEscape(input)过滤html
fatherModule.setModuelName(HtmlUtils.htmlEscape(fatherModule.getModuelName())); log.info(HtmlUtils.h ...
- TCP/IP详解 笔记一
概述: Tcp-ip让网络上的计算机进行通信,而不管计算机和操作系统是否一样. 分层结构: Tcp/ip协议族是多层协议的组合,而tcp和ip只是其中的两个协议而已. 一个通信举例: 注意图的右上方: ...
- iOS 知识点梳理
OC的理解与特性 OC作为一门面向对象的语言,自然具有面向对象的语言特性:封装.继承.多态.它既具有静态语言的特性(如C++),又有动态语言的效率(动态绑定.动态加载等).总体来讲,OC确实是一门不错 ...
- boost状态机学习二(秒表)
基础主题:秒表 下面我们要为一个机械秒表建模一个状态机.这样一个秒表通常会有两个按钮. * Start/Stop * Reset 同时有两种状态: * Stoped: 表针停留在上次停止时的位置: o ...