Another Crisis_uva12186_树形dp

来源:互联网 发布:各国工资数据 编辑:程序博客网 时间:2024/06/05 16:53

Description


最近几年,一场新的金融危机爆发了,这场危机使得很多人陷入的经济问题的困境。一些X公司的员工试图通过要求加薪度过这一难关。
X公司有着严格的等级制度,除了公司所有者小H以外,其他人都有一个直属上司。没有下属的员工称为工人,其他人则称为领导者。
为了加薪,工人们都会向他们的上司提交请愿书。当然,每个领导者都希望自己的下属能够尽可能快乐的工作,所以当至少有T%的下属提交请愿书时,那么这个领导者就会向自己的上司提交请愿书。计算百分比时,领导者只会计算直属上司是他的下属,当然,他也只会提交一次请愿书。
如果最会小H收到了超过T%的请愿书,那么他将为所有工人们加薪。现在给出公司的构架和T的数值,你需要计算至少有多少工人提交请愿书才能使得小H给工人加薪。

Input


第一行N,T(1≤N≤100000,1≤T≤100)。N表示公司的总人数(不包括小H)。每个员工编号为1到N。小H编号为0 。
第二行有N数,第I个数表示编号的员工直属上司的编号。

Output


一个数,最小需求的工人数。

Data Constraint


1≤N≤100000,1≤T≤100

Analysis


伪装成树形dp的dfs
d[i]表示节点i向父节点递交请愿书需要多少子节点递交请愿书,那么每层建一个堆,dfs找子节点的d,用前(son[i]v100)小的子节点的d更新父节点
边界条件:当i为叶节点d[i]=1

Code


#include <stdio.h>#include <cmath>#include <queue>using namespace std;struct edge{    int y,next;}e[100109];int son[100109],ls[100109],w[100109],d[100109],s[100109],maxE=0;void add(int x,int y){    e[++maxE]=(edge){y,ls[x]};    ls[x]=maxE;}void dfs(int x){    priority_queue<int,vector<int>,greater<int> >heap;    for (int i=ls[x];i;i=e[i].next)    {        if (!d[e[i].y])            dfs(e[i].y);        heap.push(d[e[i].y]);    }    for (int i=1;i<=w[x];i++)        d[x]+=heap.top(),heap.pop();}int main(){    int n,t;    scanf("%d%d",&n,&t);    for (int i=1;i<=n;i++)    {        scanf("%d",&s[i]);        add(s[i]+1,i+1);        son[s[i]+1]++;    }    for (int i=1;i<=n+1;i++)    {        w[i]=(int)(ceil(t/100.0*son[i]));        if (!son[i])            d[i]=1;    }    dfs(1);    printf("%d\n",d[1]);    return 0;}
0 0
原创粉丝点击