图的最小生成树——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 }