#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=2e5+10,INF=0x3f3f3f3f;
int n,m;
int p[N];//p和find都是并查集里的。p存储祖宗节点,find找节点的祖宗节点
struct Edge{//不需要邻接表或邻接矩阵等复杂的数据结构,只需要把边存下来就可以了,用结构体
int a,b,w;
bool operator < (const Edge &W) const{//重载小于号,按照w来排序
return w < W.w;
}
}edges[N];
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
int kruskal(){
for(int i=0;i<n;i++) p[i]=i;//并查集初始化,每个点的祖宗节点是自己
int res=0,cnt=0;//res存的是最小生成树所有边长之和,cnt存的是边数
for(int i=0;i<m;i++){
int a=edges[i].a,b=edges[i].b,w=edges[i].w;
a=find(a),b=find(b);
if(a!=b){//如果a b没联通就联通
p[a]=b;
res+=w;
cnt++;
}
}
if(cnt < n-1) return INF;//n个点连通至少需要n-1条边,最小连通树就正好需要n-1条边,小于n-1条说明不连通
return res;
}
int main(){
cin>>n>>m;
for(int i=0;i<m;i++){
int a,b,w;
cin>>a>>b>>w;
edges[i]={a,b,w};//只有两个点有边才会加入这个集合,所以从小往大找不重复的边就找到了最小生成树
}
sort(edges,edges+m);
int t=kruskal();
if(t==INF) puts("impossible");
else cout<<t<<endl;
return 0;
}
【AcWing】859. Kruskal算法求最小生成树
于 2024-09-08 15:09:57 首次发布