思路:
共 n n n个城市,要求 k k k个industry城市, n − k n-k n−k个tourism城市.
容易证明tourism城市的父节点也一定是tourism
然后这样只需要统计每个点的贡献值:
d
e
t
[
e
]
=
d
[
e
]
−
S
i
z
e
[
e
]
det[e] = d[e] - Size[e]
det[e]=d[e]−Size[e]
容易证明这个点的贡献值: 当前点的深度减去子节点个数
然后对于每个点都进行统计.最后
s
o
r
t
(
d
e
t
+
1
,
d
e
t
+
1
+
n
)
sort(det+1,det+1+n)
sort(det+1,det+1+n)
最后取前
n
−
k
n-k
n−k个作为tourism城市
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
vector <int> g[N];
int n,k,d[N],Size[N],det[N],u,v;
int cmp(int a,int b)
{
return a > b;
}
int dfs(int e,int f)
{
d[e] = d[f] + 1;Size[e] = 1;
for(int i = 0;i < g[e].size();i++)
{
int k = g[e][i];
if(k == f)continue;
Size[e] = Size[e] + dfs(k,e);
}
det[e] = Size[e] - d[e];
return Size[e];
}
void solved()
{
d[0] = 0,Size[0] = 0;
cin >> n >> k;
for(int i = 0;i < n - 1;i++)
{
cin >> u >> v;g[u].push_back(v);g[v].push_back(u);
}
dfs(1,0);
sort(det + 1,det + n + 1,cmp);
long long ans = 0;
for(int i = 1;i <= n - k;i++)
{
ans += det[i];
}
cout << ans;
}
int main()
{
#ifdef ONLINE_JUDGE
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#endif
int t = 1;
while(t--)
{
solved();
}
#ifdef LOCAL
system("pause");
#endif
return 0;
}