1. 程式人生 > >最小生成樹(Kruskal算法)

最小生成樹(Kruskal算法)

否則 father print %d main pan lib algorithm color

最小生成樹就是一張圖能生成的邊權最小的樹。

方法(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\n", ans); 57 for(int i = 1;i <= cnt;i++) 58 { 59 printf("%d %d %d\n", res[i].u, res[i].v, res[i].w); 60 } 61 return 0; 62 }

最小生成樹(Kruskal算法)