#include<iostream> #include<cstdio> #include<algorithm> #include<vector> usingnamespacestd; constint maxn = 5050; constint maxm = 200500; int n, m, ans; int fa[maxn]; classNode { public: int u, v, w; booloperator<(const Node &b) const { return w < b.w; }
} E[maxm];
intgetfa(int x) { return fa[x] == x ? x : fa[x] = getfa(fa[x]); }
boolcheck(int x, int y) { return getfa(x) == getfa(y); }
voidunion_(int x, int y) { fa[getfa(x)] = getfa(y); }
intmain() { scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) fa[i] = i; for (int i = 1; i <= m; i++) { int u, v, w; scanf("%d %d %d", &u, &v, &w); E[i].u = u; E[i].v = v; E[i].w = w; } sort(E + 1, E + m + 1); for (int i = 1; i <= m; i++) { if (check(E[i].u, E[i].v)) continue; ans += E[i].w; union_(E[i].u, E[i].v); } for (int i = 2; i <= n; i++) { if (getfa(i) != getfa(1)) { printf("orz"); return0; } } printf("%d", ans); return0; }
解释
为事先上述算法,我们需要先将边从小到大排序,每次检测 ei 两端的点 u,v 在不在已选边集对应的点集内:如果不在,则将 u 或 v 加入该点集;如果在,则跳过这条边。检测点集的过程可以用并查集实现。