AcWing 859. Kruskal算法求最小生成树
原题链接
简单
作者:
171800
,
2024-10-11 09:26:04
,
所有人可见
,
阅读 3
#include<iostream>
#include<algorithm> //对应sort函数
using namespace std;
const int N = 1e5 + 10, M = 2 * N; //边数最大为节点数的两倍
int n, m, p[N]; //p[x]表示x的祖先
// 边
struct EDGE{
int u, v, w;
}edge[M];
bool cmp(EDGE a, EDGE b){
// 从小到大排
return a.w < b.w;
}
int find(int x){
if(p[x] != x){
p[x] = find(p[x]); //迭代查询
}
return p[x];
}
int main(){
cin >> n >> m;
int u, v, w;
for(int i = 0; i < m; i++){
cin >> u >> v >> w;
edge[i] = {u, v, w}; //这种写法简洁些,也可以edge[i].u = u...
}
// 排序,需要重写比较函数
sort(edge, edge + m, cmp); //首尾地址+比较函数
//别忘了初始化,每个人一开始都是一个单独个体,都作为祖宗
for(int i = 0; i < n; i++){
p[i] = i;
}
int ans = 0, cnt = 0; //cnt用于判断是否能生成最小生成树
for(int i = 0; i < m; i++){
u = edge[i].u, v = edge[i].v, w = edge[i].w;
u = find(u), v = find(v);
// 如果两个节点不在同一个集合中
if(u != v){
p[u] = v; //两者相关联
ans += w;
cnt ++;
}
}
// 未能构成最小生成树
if(cnt != n - 1){
cout << "impossible" << endl;
}else{
cout << ans << endl;
}
return 0;
}