题目链接
思路:很显然贪心的选择最深层的,如果不够的话再逐渐由底向上选择,但这里有一个问题,如果选了上一层的节点的话对于下一层节点来说,他们能走的路就又少了一段,这个时候要怎么处理好呢?(在这里卡了Bug了好久。。。),其实只要考虑每一个节点的贡献就行了,假设我要选这个节点的话意味着这个节点的子树我都必须选,那个它的贡献就是它的深度-它的子树的大小,sort一下选最大的k个就可以了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
int dp[maxn],num[maxn];
vector<int>g[maxn],ans;
void dfs(int x,int fa,int deep)
{
dp[x]=dp[fa]+1;
num[x]=1;
for(int to:g[x])
{
if(to==fa) continue;
dfs(to,x,deep+1);
num[x]+=num[to];
}
ans.push_back(dp[x]-num[x]);
}
bool cmp(const int a,const int b)
{
return a>b;
}
int main()
{
int n,k,u,v;
scanf("%d%d",&n,&k);
for(int i=1;i<n;++i)
{
scanf("%d %d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,0,0);
ll sum=0;
sort(ans.begin(),ans.end(),cmp);
for(int i=0;i<k;++i) sum+=ans[i];
printf("%lld\n",sum);
}