AcWing 859. Kruskal算法求最小生成树
原题链接
简单
作者:
大海呀大海
,
2020-07-24 22:05:13
,
所有人可见
,
阅读 540
加油!!!
kruskal算法是将所有的边按照权重从小到大进行排序
然后,每一将当前权值最小的且没有连在一起的两个点连接在一起
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
int n, m;
int f[N];
struct Edges{
int a, b, w;
bool operator< (const Edges &W)const{
return w < W.w;//重载一下小于号,按权重来排序
}
}edges[N];
int find(int a){//并查集模板
if (f[a] != a) return f[a] = find(f[a]);
return f[a];
}
int main(){
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ ) f[i] = i;
for (int i = 0; i < m; i ++ ){
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
edges[i] = {a, b, w};
}
sort(edges, edges + m);//将顺序按照从小到大的顺序进行一个排序,,保证在连边的时候,当前权值最小
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);//找到a和b的根节点
if (a != b){//如果当前两个点没有在一个集合
f[a] = b;//将a连接在b上
res += w;//更新权重
cnt ++;//记录边数
}
}
if (cnt < n - 1) puts("impossible");//n个点至少需要n-1个边才能将所有的点给联系在一起
else cout << res << endl;
return 0;
}