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);
    }
}
posted @ 2022-03-04 23:55  Bellala  阅读(35)  评论(0)    收藏  举报