算法思路:每次选取权值最小的边,判断这两个点是否在同一个集合内,如果在则跳过,如果不在则加上这条边的权值
可以使用并查集储存结点,可以快速判断结点是否在同一集合内。
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 }