20200403 Shortest Path
下载pdf,获得更好的阅读体验。
提取码:f1ji
题意翻译
有一棵有 个结点的树(
为偶数)将其划分为
对点对,使得点对间距离综合最小,求该最小值。
多测, 组测试数据。
题解
为了值最小,显然尽量不选重的。
对于一棵子树,如果它的大小是偶数,则可以在这个子树内完成配对。
如果它是奇数,则有一个点要继续向上配对。无论是和根结点还是和其他子树,这个点额外的贡献都是父节点往这个子树的连边。
只要 dfs 一遍就可以得出答案。
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 10000 + 7;
const int maxm = 20000 + 7;
int T;
int n, Head[maxn], to[maxm], Next[maxm], w[maxm], tot;
void addedge(int x, int y, int z) {
to[++tot] = y, Next[tot] = Head[x], Head[x] = tot, w[tot] = z;
}
void add(int x, int y, int z) {
addedge(x, y, z); addedge(y, x, z);
}
void clear(void) {
tot = 0;
memset(Head, 0, sizeof(Head));
memset(Next, 0, sizeof(Next));
}
void Init(void) {
scanf("%d", &n);
for(int i = 1, x, y, z; i < n; i++) {
scanf("%d%d%d", &x, &y, &z);
add(x, y, z);
}
}
LL ans;
int dfs(int x, int f, LL l) {
int size = 1;
for(int i = Head[x]; i; i = Next[i]) {
int y = to[i];
if(y == f) continue;
size += dfs(y, x, (LL)w[i]);
}
if(size & 1) ans += l;
return size;
}
void Work(void) {
ans = 0;
dfs(1, 0, 0);
printf("%lld\n", ans);
}
int main(void) {
scanf("%d", &T);
while(T--) {
clear();
Init();
Work();
}
} 
京公网安备 11010502036488号