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

 

------------恢复内容结束------------

posted @ 2020-08-20 10:11  Rain~~  阅读(163)  评论(0编辑  收藏  举报