859-Kruskal算法求最小生成树
859. Kruskal算法求最小生成树 - AcWing题库
题目描述
关系
内容
给定一个
求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。
给定一张边带权的无向图
由
输入格式
第一行包含两个整数
接下来
输出格式
共一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。
数据范围
图中涉及边的边权的绝对值均不超过
输入样例:
4 5
1 2 1
1 3 2
1 4 3
2 3 2
3 4 4
输出样例:
6
问题分析
思路分析
Kruskal 算法的贪心思路是选择边权最小的边来实现的。时间复杂度为
借用一个并查集,按照边权从小到大枚举所有边,如果两个边不在同一个集合之内,就加入。
执行流程设计 ef
总结
代码实现
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, m;
int p[N];
struct Edge {
int a, b, c;
bool operator< (const Edge &e) const {
return c < e.c;
}
} e[N];
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++) p[i] = i;
for (int i = 0; i < m; i++) {
int a, b, c;
cin >> a >> b >> c;
e[i] = {a, b, c};
}
sort(e, e + m);
int cnt = n, res = 0; // cnt 表示还未被加入生成树的节点数
for (int i = 0; i < m; i++) {
int a = e[i].a, b = e[i].b, c = e[i].c;
if (find(a) != find(b)) {
p[find(b)] = find(a);
res += c;
cnt--;
}
}
if (cnt > 1) puts("impossible"); // cnt > 1 意味有多个生成树,这是不可能的
else printf("%d\n", res);
return 0;
}