1 介绍
kruskal算法的关键步骤为:
- 将所有边按照权重从小到大排序。
- 定义集合S,表示生成树。
- 枚举每条边(a,b,c),起点a,终点b,边长c。如果结点a和结点b不连通(用并查集来维护),则将这条边加入到集合S中。
kruskal算法的时间复杂度为O(mlogm),它用来解决稀疏图的最小生成树问题。
2 训练
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = 2e5 + 10;
int n, m;
int p[N];
struct Edge {
int a;
int b;
int w;
}edges[M];
int find(int x) {
if (p[x] == x) return x;
p[x] = find(p[x]);
return p[x];
}
void kruskal() {
sort(edges, edges+m, [](const Edge &a, const Edge &b) {
return a.w < b.w;
});
for (int i = 1; i <= n; ++i) p[i] = i;
long long res = 0;
int cnt = 0;
for (int i = 0; i < m; ++i) {
int a = edges[i].a;
int b = edges[i].b;
int w = edges[i].w;
int pa = find(a);
int pb = find(b);
if (pa != pb) {
p[pa] = pb;
res += w;
cnt++;
}
}
if (cnt < n-1) {
cout << "impossible" << endl;
} else {
cout << res << endl;
}
return;
}
int main() {
cin >> n >> m;
for (int i = 0; i < m; ++i) {
cin >> edges[i].a >> edges[i].b >> edges[i].w;
}
kruskal();
return 0;
}