cf1280 C. Jeremy Bearimy(思维)
题意:
在带边权的树中找所有两两不相交的点对(每个点都属于一个点对),输出每对点的距离之和的最小值和最大值。
思路:
考虑每一条边。删去这条边就能把树中的点分成两个集合
最小值,尽量不用当前边:如果两个集合均有偶数个点,那么这条边可以不选,否则必须选。
最大值,尽量用当前边:取两个集合中较小的者的大小
int siz[N];
void dfs(int u, int fa)
{
siz[u] = 1;
for(int i = h[u]; i; i = ne[i])
{
int v = e[i], z = w[i]; if(v == fa) continue;
dfs(v, u); siz[u] += siz[v];
int c1 = (n-siz[v]), c2 = siz[v];
ans0 += (ll)z * ((c1&1) || (c2&1)); //一边是奇就行
ans1 += (ll)z * min(c1, c2);
}
}

浙公网安备 33010602011771号