Jzoj4765 Crisis

X公司有着严格的等级制度,除了公司所有者小H以外,其他人都有一个直属上司。没有下属的员工称为工人,其他人则称为领导者。
为了加薪,工人们都会向他们的上司提交请愿书。当然,每个领导者都希望自己的下属能够尽可能快乐的工作,所以当至少有T%的下属提交请愿书时,那么这个领导者就会向自己的上司提交请愿书。计算百分比时,领导者只会计算直属上司是他的下属,当然,他也只会提交一次请愿书。

如果最会小H收到了超过T%的请愿书,那么他将为所有工人们加薪。现在给出公司的构架和T的数值,你需要计算至少有多少工人提交请愿书才能使得小H给工人加薪。

树形DP

我们设f[i]表示使i提交申请的代价,叶子结点的代价为1,size[i]为i的直接下属

那么f[i]=min{Σf[j] (j∈son[i] 且 Σsize[j] >= size[i]*T%)}

那么我们处理处每个子树的f,排序取前面最小的直到取到T%为止

#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> G[100010],s[100010];
int n,T;
int cal(int x){
	if(G[x].size()==0) return 1;
	for(int i=0,z=G[x].size();i<z;++i)
		s[x].push_back(cal(G[x][i]));
	sort(s[x].begin(),s[x].end());
	int ans=0;
	for(int i=0,z=s[x].size();i*100<z*T;++i) ans+=s[x][i];
	return ans;
}
int main(){
	scanf("%d%d",&n,&T);
	for(int x,i=1;i<=n;++i){
		scanf("%d",&x);
		G[x].push_back(i);
	}
	printf("%d\n",cal(0));
}

posted @ 2017-10-24 20:02  扩展的灰(Extended_Ash)  阅读(71)  评论(0编辑  收藏  举报