最小生成树(Kruskal算法)
Posted scalecx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小生成树(Kruskal算法)相关的知识,希望对你有一定的参考价值。
最小生成树就是一张图能生成的边权最小的树。
方法(Kruskal算法):将所有边权从小到大排序,然后一条一条边检查,如果加入这条边形成了回路,那么不加入树中,否则加入。至于如何判断回路,用并查集维护即可。
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #include<algorithm> 7 #include<string> 8 #include<vector> 9 #include<queue> 10 #include<stack> 11 using namespace std; 12 const int MaxN = 1e5; 13 const int Inf = 1 << 30; 14 typedef struct 15 { 16 int u, v, w;//连接u,v两点权值为w的边 17 } Power; 18 19 Power edge[MaxN+5]; 20 Power res[MaxN+5]; 21 int father[MaxN+5]; 22 int n, m;//点和边的数量 23 24 bool cmp(Power a, Power b) 25 { 26 return a.w < b.w; 27 } 28 29 int Find(int x) 30 { 31 if(father[x] == x) return x; 32 else return father[x] = Find(father[x]); 33 } 34 35 int main() 36 { 37 scanf("%d %d", &n, &m); 38 for(int i = 1;i <= n;i++) father[i] = i; 39 for(int i = 1;i <= m;i++) 40 { 41 scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w); 42 } 43 sort(edge + 1, edge + 1 + m, cmp); 44 int ans = 0, cnt = 0; 45 for(int i = 1;i <= m;i++) 46 { 47 int u = edge[i].u, v = edge[i].v, w = edge[i].w; 48 if(Find(u) != Find(v)) 49 { 50 father[Find(u)] = Find(v); 51 ans += w; 52 cnt++; 53 res[cnt].u = u; res[cnt].v = v; res[cnt].w = w; 54 } 55 } 56 printf("%d ", ans); 57 for(int i = 1;i <= cnt;i++) 58 { 59 printf("%d %d %d ", res[i].u, res[i].v, res[i].w); 60 } 61 return 0; 62 }
以上是关于最小生成树(Kruskal算法)的主要内容,如果未能解决你的问题,请参考以下文章