题意:
解法:
题目是求总距离,也就是总边数.
这种题一个技巧是分别考虑每条边的贡献.
对于边(x,v), 设x左侧有L个大学,v右侧有R个大学,那么最优配对下,这条边的贡献就是min(L,R).
因为最优情况下,一定要跨这条边匹配,答案才是最优的.
举个例子:
对于黑色的边来说,不跨边的匹配方式是:a和b匹配,c和d匹配
这样的匹配方式一定显然不如a和c匹配,b和d匹配。
因为这样的匹配方式,相比于原有的匹配方式,原有的边不变,额外增加了黑色边的贡献。
Code:
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define int long long
#define PI pair<int, int>
const int maxm=3e5+5;
const int mod=1e9+7;
int n,k;
int a[maxm];
int sz[maxm];
vector<int>g[maxm];
int ans=0;
void dfs(int x,int fa){
sz[x]=a[x];
for(int v:g[x]){
if(v==fa)continue;
dfs(v,x);
ans+=min(k*2-sz[v],sz[v]);
sz[x]+=sz[v];
}
}
void solve() {
cin>>n>>k;
for(int i=1;i<=k*2;i++){
int x;cin>>x;
a[x]=1;
}
for(int i=1;i<n;i++){
int l,r;cin>>l>>r;
g[l].push_back(r);
g[r].push_back(l);
}
dfs(1,1);
cout<<ans<<endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
#ifndef ONLINE_JUDGE
freopen("../in.txt", "r", stdin);
freopen("../out.txt", "w", stdout);
#endif
#ifdef MULTI_CASE
int T;
cin >> T;
while (T--)
#endif
solve();
return 0;
}