最小生成樹(Kruskal算法)
阿新 • • 發佈:2018-07-19
否則 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 intn, 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算法)