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;
}