题目链接:Denouncing Mafia
画画图我们就可以发现,每次最优肯定是选最长的链,然后算上这条链对其他链的影响,然后再选最长的链,然后做k次。
然后我们可以发现,这就是一个长链剖分,选K条最长链。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int n,k,bl[N],dep[N],son[N],cnt,s[N],res;
vector<int> g[N],v;
void dfs1(int x){
dep[x]=1;
for(int to:g[x]){
dfs1(to); dep[x]=max(dep[x],dep[to]+1);
if(dep[to]>dep[son[x]]) son[x]=to;
}
}
void dfs2(int x,int belong){
bl[x]=belong; s[belong]++;
if(son[x]) dfs2(son[x],belong);
for(int to:g[x]) if(to!=son[x]) dfs2(to,to);
}
signed main(){
cin>>n>>k;
for(int i=2,x;i<=n;i++) scanf("%d",&x),g[x].push_back(i);
dfs1(1); dfs2(1,1);
for(int i=1;i<=n;i++) if(s[i]) v.push_back(s[i]);
sort(v.begin(),v.end(),greater<int>());
for(int i=0;i<v.size()&&i<k;i++) res+=v[i];
cout<<res;
return 0;
}