Loading

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;
}
posted @ 2024-06-29 22:38  你说得太对辣  阅读(9)  评论(0)    收藏  举报