n个点的树型结构,选择k个工业城市,其他都是旅游城市,问所有工业城市到1节点的幸福值总和最大多少。幸福值为经过的旅游城市的个数。
优先的想法肯定是深度越大越好。
但是考虑一下,对于一棵树的内部节点而言,一定要经过根u,如果根被选为工业城市,那么增加的幸福值就是dep[u]-siz[u]
什么意思呢?就是如果选了这个节点为工业城市,那么子树内部的工业城市的幸福值都要减少1,
之所以减去的是树的大小,是因为基于深度越大越好,所以肯定是优先把树内部的点选上,而增加的就是u到节点1的路径长度也就是深度。
首先以dep[x]-siz[x]从大到小排序取前k大的和即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int> e[1 << 21];
int siz[1 << 21], dep[1 << 21];
int cnt[1 << 21];
void dfs(int x, int f)
{
    dep[x] = dep[f] + 1;
    siz[x] = 1;
    for (auto it : e[x])
    {
        if (it == f)
            continue;
        dfs(it, x);
        siz[x] += siz[it];
    }
}
int main()
{
    int n, k;
    cin >> n >> k;
    for (int i = 1; i < n; i++)
    {
        int x, y;
        cin >> x >> y;
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs(1, -1);
    for (int i = 1; i <= n; i++)
        cnt[i] = i;
    sort(cnt + 1, cnt + 1 + n, [](int x, int y) {
        return dep[x] - siz[x] > dep[y] - siz[y];
    });
    ll ans = 0;
    for (int i = 1; i <= k; i++)
    {
        ans += dep[cnt[i]] - siz[cnt[i]];
    }
    cout << ans << endl;

    return 0;
}