AcWing 859. Kruskal算法求最小生成树
原题链接
简单
作者:
郡呈
,
2019-08-12 11:12:48
,
所有人可见
,
阅读 2140
/*
res 最小生成树中的权重之和
cnt 当前加了多少条边
1.将所有边按权重排序O(mlogm)
2.枚举每条边(并查集应用)
if a,b 不连通
加入集合
3.需重载<
bool operator < (const Edge &C) const {
return w < C.w;
}
*/
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5+10, M = 2e5+10, INF = 0x3f3f3f3f;
int n, m;
int p[N];//祖宗节点
struct Edge {
int u, v, w;
bool operator < (const Edge & T) const {
return w < T.w;
}
}edges[M];
int find(int x) {
//并查集核心
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
int kruskal() {
sort(edges, edges+m);
for(int i = 1; i <= n; i++) p[i] = i; //初始化并查集
int res = 0, cnt = 0;
//res 最小生成树中的权重之和
//cnt 当前加了多少条边
for(int i = 0; i < m; i++) {
auto t = edges[i];
t.u = find(t.u), t.v = find(t.v);
if(t.u != t.v) {
p[t.u] = t.v;
res += t.w;
cnt++;
}
}
if(cnt < n - 1) return INF;
return res;
}
int main() {
cin >> n >> m;
int u, v, w;
for(int i = 0; i < m; i++) {
cin >> u >> v >> w;
edges[i] = {u, v, w};
}
//注意读入的是m又犯低级错误
int x = kruskal();
if(x > INF/2) puts("impossible");
else cout << x << endl;
}
你好,我想请教一下祖宗节点是什么,p[N]为什么要初始化呢??
祖宗节点:数据结构中一般指父节点.在并查集里代表的是不同集合中的根节点.
p[N]:用于保存父节点.初始化是因为开始状态默认每个点为一个集合的根节点,而一般并查集中根的父节点设为自己.
不知道这样说明清不清楚,如果不清楚可以百度并查集了解一下相关知识.
想起来了,谢谢啦!