题目大意: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;
}


京公网安备 11010502036488号