主要是针对边的操作
- 时间复杂度分析:
将所有边按权重从小到大排列(O(m log m))
枚举所有边,若边的两点没有连通,就加入这条边。(O(m))
思路简单,实际时间超级低
,优美的算法。- 用于
稀疏图
,就是那种边比较少
的;- p[N]是并查集;
- 本算法思路:
从小到大枚举所有边。
找到a、b的祖宗节点,若不一样即不连通
res代表当前所有树边的权重之和
cnt代表当前存了多少条边。
若cnt < n - 1说明图不连通。
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
int n, m;
int p[N];
struct E {
int a, b, w;
bool operator<(E const &W) const { return w < W.w; }
} e[N];
//查找点是否存在于联通块中
int find(int x) {
if (p[x] != x)
p[x] = find(p[x]); /* 如果p[x]不是x的祖宗节点,继续找。*/
return p[x];
}
int main() {
cin >> n >> m;
for (int i = 0; i < m; i++) {
int a, b, w;
cin >> a >> b >> w;
e[i] = { a, b, w };
}
//先按照权值大小进行排序:
sort(e, e + m);
//初始化父节点
for (int i = 1; i < n; i++) p[i] = i;
int res = 0, cnt = 0;
for (int i = 0; i < m; i++) {
int a = e[i].a, b = e[i].b, w = e[i].w;
a = find(a), b = find(b);
if (a != b) {
p[a] = b;
res += w;
cnt++;
}
}
if (cnt < n - 1) cout << "impossible";
else cout << res;
return 0;
}