题意
给出一棵树,在里面加上若干边使它变成一个完全图,且图中的最小生成树还是这棵树,求图最小的边权总和。
思路
见走廊泼水节。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
struct node{
int x, y, w;
}e[40001];
int t, n, tot, maxs;
int fa[20001], s[20001];
long long ans;
int cmp(node x, node y) {
return x.w < y.w;
}
int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
int main() {
scanf("%d", &t);
for (; t; t--) {
ans = 0;
memset(s, 0, sizeof(s));
scanf("%d", &n);
for (int i = 1; i < n; i++) {
scanf("%d %d %d", &e[i].x, &e[i].y, &e[i].w);
fa[i] = i;
s[i] = 1;
ans += e[i].w;
}
fa[n] = n;
s[n] = 1;
std::sort(e + 1, e + n, cmp);
int a, b;
for (int i = 1; i < n; i++) {
a = find(e[i].x);
b = find(e[i].y);
if (a == b) continue;
ans += (long long)(s[a] * s[b] - 1) * (e[i].w + 1);
fa[a] = b;
s[b] += s[a];
}
printf("%lld\n", ans);
}
}