#include<iostream>#include<cmath>#include<cstring>#include<cstdio>#include<algorithm>#define ll long long
using namespace std;
const int maxn=400005;
ll first[maxn],last[maxn],next[maxn],num,n,i,t,j,k,l,size[maxn],m,x,y,ans;
bool bz[maxn];
void lian(intx,inty){
last[++num]=y;next[num]=first[x];first[x]=num;
}
void dg(ll x,ll y){
ll t;
for (t=first[x];t;t=next[t]){
if (last[t]==y) continue;
dg(last[t],x);
size[x]+=size[last[t]];
ans+=min(size[last[t]],2*m-size[last[t]]);
}
if (bz[x]) size[x]++;
}
int main(){
//freopen("data.in","r",stdin);
scanf("%d%d",&n,&m);
for (i=1;i<=2*m;i++)
scanf("%d",&x),bz[x]=true;
for (i=1;i<n;i++)
scanf("%d%d",&x,&y),lian(x,y),lian(y,x);
dg(1,0);
printf("%lld\n",ans);
}
Description给出n个点的树,及2*k个节点,给他们配对,使得他们之间的距离和最大。求距离和Data Constraint2 ≤ n ≤ 200 000, 1 ≤ k ≤ n / 2Solution我们发现对于一条边,当它左边有要求配对x个节点,右边有要求配对y个节点,那么显然最大的方案就是min(x,y)。所以,我们照着这样对每条边判断一下就好。时间复杂度O(N)。代码#include<i