[图论与代数结构 301] 最短树问题_1 - 洛谷
分三步,输入,排序,并查集连接n次
using ll = long long;
constexpr int N = 2e5 + 5;
constexpr int M = 5e5 + 5;
ll ans, sum, n, m;struct DSU {std::vector<int> f, siz;DSU() {}DSU(int n) {init(n);}void init(int n) {f.resize(n);std::iota(f.begin(), f.end(), 0);siz.assign(n, 1);}int find(int x) {while (x != f[x]) {x = f[x] = f[f[x]];}return x;}bool merge(int x, int y) {x = find(x);y = find(y);if (x == y) return false;siz[x] += siz[y];f[y] = x;return true;}int size(int x) {return siz[find(x)];}
};DSU dsu(N);struct edge {ll from, to, value;
};std::vector<edge> e(M*2);void Kruskal() {ll tot = 0;//按值的大小排序std::sort(e.begin() + 1, e.begin() + 1 + m, [&](const edge& x, const edge& y) {return x.value < y.value;});//枚举边值for (int i = 1; i <= m; i++) {//连接n次if (dsu.merge(e[i].to, e[i].from)) {tot++;ans += e[i].value;}if (tot == n) break;}
}int main() {//输入std::cin >> n >> m;for (int i = 1; i <= m; i++) {std::cin >> e[i].from >> e[i].to >> e[i].value;}Kruskal();//打印答案std::cout << ans << '\n';return 0;
}
【模板】最小生成树 - 洛谷
这道题增加了一个连通性的判断
//改一下数据,增加一个判断连通性
constexpr int N = 5000 + 5;
constexpr int M = 2e5 + 5;
int main() {std::cin >> n >> m;for (int i = 1; i <= m; i++) {std::cin >> e[i].from >> e[i].to >> e[i].value;}Kruskal();//连接完for (int i = 1; i <= m; i++) {dsu.merge(e[i].to, e[i].from);}//枚举节点看父节点是否相同bool connected = true;for (int i = 1; i <= n; ++i) {if (dsu.find(i) != dsu.find(1)) {connected = false;break;}}if (connected) {std::cout << ans << '\n';}else {std::cout << "orz" << '\n';}return 0;
}