Codeforces Round 364 (Div. 2)
A.
B.
对每个点分开来计算被经过了多少次,发现只要有两个点在它的不同侧就一定会经过这个点,然后就 dfs 一遍即可。
设一条边左边的点的数量为 \(x\),答案即为 \(\sum \min(x, 2k - x)\)。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e6 + 7;
int p[N];
struct edge {
int next, to;
}e[N];
int head[N], ecnt;
void addedge(int u, int v) {
e[++ ecnt].to = v;
e[ecnt].next = head[u];
head[u] = ecnt;
}
int ans;
int cnt[N];
void dfs(int u, int fa) {
for(int i = head[u]; ~i; i = e[i].next) {
int v = e[i].to;
if(v == fa) continue;
dfs(v, u);
cnt[u] += cnt[v];
}
}
signed main() {
memset(head, -1, sizeof head);
int n, k;
cin >> n >> k;
for(int i = 1; i <= 2 * k; i ++) cin >> p[i], cnt[p[i]] = 1;
for(int i = 1; i < n; i ++) {
int u, v;
cin >> u >> v;
addedge(u, v);
addedge(v, u);
}
dfs(1, 0);
int ans = 0;
for(int i = 1; i <= n; i ++) ans += min(cnt[i], 2 * k - cnt[i]);
cout << ans << endl;
}

浙公网安备 33010602011771号