題目鏈接: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;
}