【codevs】2796 最小完全图 | Kruskal
题意
若一个图的每一对不同顶点都恰有一条边相连,则称为完全图。
最小生成树MST在Smart的指引下找到了你,希望你能帮它变成一个最小完全图(边权之和最小的完全图)。
注意:必须保证这个最小生成树MST对于最后求出的最小完全图是唯一的。
数据范围
30%的数据:n<1000;
100%的数据:n≤20000,所有的边权<231。
题解
1、Kruskal 求最小生成树
先将边按照边权从小到大排序。
然后按顺序检查该边的两个端点如果在两个集合中,那么合并它们,直到所有点都在同一集合中。
Kruskal#include <cstdio> #include <algorithm> const int MAXN = 100050; int n, dad[MAXN], ans; struct Edge { int form, to, pow; bool operator < (Edge a) { return pow < a.pow; } } edge[MAXN]; void addE(int x, int y, int z, int ma) { edge[ma].form = x; edge[ma].to = y; edge[ma].pow = z; } int getdad(int x) { return dad[x] == x ? x : getdad(dad[x]); } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) dad[i] = i; for (int i = 1; i < n; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); addE(a, b, c, i); } std::sort(edge + 1, edge + n); for (int i = 1; i <= n; i++) { int u = edge[i].form, v = edge[i].to; if (getdad(u) != getdad(v)) dad[u] = getdad(dad[v]), ans += edge[i].pow; } printf("%d\n", ans); return 0; }2、对于这一道题,给我们最小生成树,要求求出最小完全图。
一开始所有点都在不同的集合中, 我们每读入一次边就是将该边的端点所在的两个集合连上一条边,但我们想让这两个集合完全联通,也就是说把两个集合中的元素两两连边,要注意的一点是这些边的权值至少是我们读入的那条边的权值加一,否则将不满足必须保证这个最小生成树MST对于最后求出的最小完全图是唯一的 。
AC代码
辣鸡 codevs,害我 CE#include <cstdio> #include <iostream> #include <algorithm> #define ll long long const int MAXN = 100050; int n; ll dad[MAXN], sz[MAXN], ans; struct Edge { int from, to; ll pow; /* bool operator < (Edge a) { // 辣鸡 codevs!!!为什么不让我用 operator !!! return pow < a.pow; }*/ } e[MAXN]; bool cmp(Edge a, Edge b) { return a.pow < b.pow; } void addE(int x, int y, int z, int ma) { e[ma].from = x; e[ma].to = y; e[ma].pow = z; } int getdad(int x) { return dad[x] == x ? x : getdad(dad[x]); } int main() { scanf("%d", &n); ans = 0; for (int i = 1; i <= n; i++) dad[i] = i, sz[i] = 1; for (int i = 1; i < n; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); addE(a, b, c, i); // printf("%d\n", e[i].pow); } std::sort(e + 1, e + n, cmp); for (int i = 1; i < n; i++) { int u = getdad(e[i].from), v = getdad(e[i].to); ans += sz[u] * sz[v] * (e[i].pow + 1) - 1; dad[u] = v, sz[v] += sz[u]; } printf("%lld\n", ans); return 0; }


浙公网安备 33010602011771号