题目大意:n个点的树,有m*2个点有磁铁,如果配对使得m对磁铁之间的距离之和最大?
对于每一条边,左边有x个磁铁,右边有y个磁铁,要想距离大,那么尽量左右两边互相配对,最多可以配min(x, y)对。每条边都是如此。
#include <bits/stdc++.h> #define N 200005 using namespace std; int n, m, i, j, k, a, b, ans, s[N], h[N]; struct AB{ int a, b, n; } d[N*2]; void cun(int a, int b){ d[++k].a = a, d[k].b = b; d[k].n = h[a], h[a] = k; } void dfs(int a, int p){ int b, i; for(i=h[a]; i; i=d[i].n){ b = d[i].b; if(b != p){ dfs(b, a); s[a] += s[b]; ans += min(s[b], m*2-s[b]); } } } int main(){ scanf("%d%d", &n, &m); for(i=1; i<=m*2; i++){ scanf("%d", &j); s[j] = 1; } for(i=1; i<n; i++){ scanf("%d%d", &a, &b); cun(a, b); cun(b, a); } dfs(1, 0); printf("%d\n", ans); return 0; }