最小生成树kruskal算法
------------恢复内容开始------------
kruskal算法是一种求最小生成树的算法。
思路:贪心思想,每次取最小的一条边,如果成环则取下一条最小的边,直到取了(N-1)条边为止(N是点的个数)。
用并查集判断是否成环:如果在一个集合内就成环,如果不在一个集合内就把这条边添加到集合里。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<string> 6 using namespace std; 7 int n,m,i,j,u,v,total; 8 struct edge{ 9 int start,to;int val; 10 friend bool operator <(edge x,edge y){ 11 return x.val<y.val; 12 } 13 }Edge[2000005]; 14 int f[100000]; 15 int ans; 16 int find(int x)//并查集部分 17 { 18 if (f[x]==x) return x; 19 else{ 20 f[x]=find(f[x]); 21 return f[x]; 22 } 23 } 24 void kruskal()//最小生成树 25 { 26 27 for(int i=1;i<=m;i++) 28 { 29 u=find(Edge[i].start); 30 v=find(Edge[i].to); 31 if(u==v) continue;//判断在不在同一个并查集里面,在就下一个循环 32 ans+=Edge[i].val;//不在,就加上答案 33 f[u]=v;//连接两个并查集 34 total++; 35 if(total==n-1) break;//当形成了最小生成树后,退出 36 } 37 } 38 int main() 39 { 40 scanf("%d%d",&n,&m); 41 for(i=1;i<=n;i++) f[i]=i; 42 for(i=1;i<=m;i++) 43 { 44 scanf("%d%d%d",&Edge[i].start,&Edge[i].to,&Edge[i].val); 45 } 46 sort(Edge+1,Edge+m+1);//快排边长 47 kruskal(); 48 printf("%d",ans); 49 return 0; 50 }
------------恢复内容结束------------