挖沟
挖沟
https://ac.nowcoder.com/acm/problem/17509
最小生成树模板题
直接上代码
大概意思解释一下,
1.首先最小生成树的克鲁斯卡尔算法相当于并查集的升级版,与并查集不同的是,他要对边的权值进行排序,并且最后生成树的边是m-1条
2.我们用一个结构体内嵌比较函数去记录和排序边,外加一个路径压缩和一个判断联通的函数
3.然后我们对已经排好队的边进行加边操作,如果两个边没有被联通,那我们就加边,不断地记录这个操作,最后得出来的就是最小生成树的最小权值之和
方法一
#include <bits/stdc++.h> using namespace std; const int maxn = 1e6 + 10; int pre[maxn]; struct node { int u, v, e; bool operator<(const node x) { return e < x.e; } } w[maxn]; int find(int x) { return pre[x] == x ? x : pre[x] = find(pre[x]); } int join(int x, int y) { int a = find(x); int b = find(y); if (a != b) { pre[a] = b; return 1; } return 0; } int main() { int n, m, ans = 0; scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) pre[i] = i; for (int i = 1; i <= m; ++i) scanf("%d%d%d", &w[i].u, &w[i].v, &w[i].e); sort(w + 1, w + m + 1); for (int i = 1; i <= m; ++i) { if (join(w[i].u, w[i].v)) ans += w[i].e; } printf("%d\n", ans); }
方法二
#include <bits/stdc++.h> using namespace std; const int maxn = 1e6 + 10; int pre[maxn]; struct node { int u, v, e; bool operator<(const node x) { return e < x.e; } } w[maxn]; int find(int x) { return pre[x] == x ? x : pre[x] = find(pre[x]); } void join(int x, int y) { pre[find(x)] = find(y); } int main() { int n, m, ans = 0; scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) pre[i] = i; for (int i = 1; i <= m; ++i) scanf("%d%d%d", &w[i].u, &w[i].v, &w[i].e); sort(w + 1, w + m + 1); for (int i = 1; i <= m; ++i) { if (find(w[i].u) != find(w[i].v)) { join(w[i].u, w[i].v); ans += w[i].e; } } printf("%d\n", ans); }
牛客课后习题题解 文章被收录于专栏
等待蜕变