Denouncing Mafia

題目鏈接: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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章