最小生成树kruskal模板

算法思路:每次选取权值最小的边,判断这两个点是否在同一个集合内,如果在则跳过,如果不在则加上这条边的权值

可以使用并查集储存结点,可以快速判断结点是否在同一集合内。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<vector>
 6 #include<stack>
 7 #include<cstdio>
 8 #include<map>
 9 #include<set>
10 #include<string>
11 #include<queue>
12 using namespace std;
13 #define inf 0x3f3f3f3f
14 typedef long long ll;
15 map<ll,ll> mp;
16 const int maxn=1e5+50;//边数
17 struct edg{
18     int u;
19     int v;
20     int w;
21     bool operator < (const edg e)
22     const{
23         return w<e.w;
24     }
25 }st[maxn];
26 int fa[maxn];//并查集
27 int cnt;//边数
28 void addedg(int u,int v,int w){
29     st[cnt].u=u;
30     st[cnt].v=v;
31     st[cnt++].w=w;
32 }
33 int find(int i){
34     if(fa[i]==-1)
35     return i;
36     else
37     return find(fa[i]);
38 }
39 int kruskal(int n){
40     sort(st,st+cnt);
41     memset(fa,-1,sizeof(fa));
42     int u,v;
43     int ans=0,count=0;
44     int f1,f2;
45     for(int i=0;i<cnt;i++){
46         u=st[i].u;
47         v=st[i].v;
48         f1=find(u);
49         f2=find(v);
50         if(f1!=f2){
51             fa[f1]=f2;
52             ans+=st[i].w;
53             count++;
54         }
55     }
56     if(count==n-1){
57         return ans;
58     }
59     else{
60         return -1;
61     }
62 }
63 int main(){
64     int n,m;
65     int u,v,w;
66     int ans;
67     cin>>n>>m;//点,边的数量 
68     cnt=0;
69     for(int i=0;i<m;i++){
70         cin>>u>>v>>w;
71         addedg(u,v,w);
72     }
73     ans=kruskal(n);
74     if(ans==-1){
75         cout<<"该图没有连通"<<endl; 
76     }
77     else{
78         cout<<ans<<endl;
79     }
80     return 0;
81 } 
原文地址:https://www.cnblogs.com/Zhi-71/p/10021573.html