图的最小生成树——Kruskal算法

Kruskal算法

图的最小生成树的算法之一,运用并查集思想来求出最小生成树。

基本思路就是把所有边从小到大排序,依次遍历这些边。如果这条边所连接的两个点在一个连通块里,遍历下一条边,如果不在,就把这条边加入连通块,这样就可以保证生成树的边权最小。

我们使用并查集来判断两个点是否在同一个连通块里,如果在,他们的find会相同,否则不在。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define N 42000
 4 using namespace std;
 5 struct hehe{
 6     int a1;
 7     int b1;
 8     int c1;
 9 }edge[N];
10 int n,m,a,b,c,father[N],num,tot,k;
11 int cmp(hehe x,hehe y){
12     return x.c1<y.c1;
13 }
14 int find(int x){
15     if(father[x]!=x)
16         father[x]=find(father[x]);
17     return father[x];
18 }
19 int main(){
20     scanf("%d%d",&n,&m);
21     for(int i=1;i<=m;++i){
22         scanf("%d%d%d",&a,&b,&c);
23         edge[++num].a1=a;
24         edge[num].b1=b;
25         edge[num].c1=c;
26     }
27     for(int i=1;i<=n;++i)
28         father[i]=i;
29     sort(edge+1,edge+m+1,cmp);
30     for(int i=1;i<=m;++i)
31         if(find(edge[i].a1)!=find(edge[i].b1)){
32             father[edge[i].a1]=edge[i].b1;
33             tot+=edge[i].c1;
34             k++;
35             if(k==n-1)
36                 break;
37         }
38     printf("%d",tot);
39     return 0;
40 }
View Code

 

posted @ 2017-05-07 09:01  江屿  阅读(361)  评论(0编辑  收藏  举报