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) 和 ...
随机推荐
- 序列化和反序列化的几种方式(DataContractSerializer)(二)
DataContractSerializer 类 使用提供的数据协定,将类型实例序列化和反序列化为 XML 流或文档. 无法继承此类. 命名空间: System.Runtime.Serializati ...
- 第一课:js命名空间的介绍,js对象的扩展以及js数组化
1.命名空间: js里面的命名空间就是使用对象的属性来扩展的.比如,用户定义一个A对象,A对象下面有B属性和C属性,同时B属性和C属性又是对象.因此A={B:{},C:{}},这时用户就可以在B对象和 ...
- 利用 NSSortDescriptor 对 NSMutableArray 排序
有时我们在NSMutableArray中存的是网络请求返回的数据,而每一个元素又是一个NSDictionary,如果这时候需要把数组中的元素按照每个元素字典中某一个key来排序,那么我们可以利用Obj ...
- “耐撕”团队 2016.03.30 站立会议
1. 时间: 16:45--17:05 总计:20分钟 2. 成员: Z 郑蕊 * 组长 (博客:http://www.cnblogs.com/zhengrui0452/), P 濮成林(博客:ht ...
- 团队项目--关于QQ项目的运行和总结
目前为止该QQ项目实现如下功能:添加好友到好友列表,可以把好友在不同分类中移动,同时支持离线查找添加好友,离线更换头像,离线发送消息,保存所有好友聊天记录,发送窗口抖动,查看对方信息,更改/添加信息等 ...
- OC基础--ARC的基本使用
一.ARC的判断准则:只要没有强指针指向对象,就会释放对象 二.ARC特点: 1>不允许使用release.retain.retainCount 2>允许重写dealloc,但是不允许调用 ...
- UVA5874 Social Holidaying 二分匹配
二分匹配简单题,看懂题意,建图比较重要. #include<stdio.h> #include<string.h> #define maxn 1100 int map[maxn ...
- 抓包利器Fiddler
1).Fiddler安装 a.下载地址: http://fiddler2.com/get-fiddler b.安装:省略(下一步...下一步即可) 2).Fiddler配置 a.允许远程计算机连接Fi ...
- openSSL命令、PKI、CA、SSL证书原理
相关学习资料 http://baike.baidu.com/view/7615.htm?fr=aladdin http://www.ibm.com/developerworks/cn/security ...
- FluentData,它是一个轻量级框架,关注性能和易用性。
http://www.cnblogs.com/zengxiangzhan/p/3250105.html FluentData,它是一个轻量级框架,关注性能和易用性. 下载地址:FlunenData.M ...