最小生成树(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\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 }

 

posted @ 2018-07-19 11:27  Lightfall  阅读(739)  评论(0编辑  收藏  举报