题意:一个老板和n个员工组成树状结构,每个员工都有自己的唯一上司,老板的编号为0,员工1~n,工人们打算签署一个志愿书给老板,但无法跨级,当一个中级员工(非是工人的员工)的直属下属中不小于T%的人签字时,他也会签字并且递给他的直属上司,问:要让老板收到请愿书至少需要多少个工人签字。
注意:这里要求的是最底层工人(即叶子结点)的最少个数。
思路:从0dfs,自底向上,对每一个结点当做跟来排序他的孩子(按ans数从小到大),然后计算至少需要多少个孩子,再往上一层传递,典型的树形DP。
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=100005;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
vector<int> v[maxn];
int n,t;
int dfs(int u)
{
if(v[u].empty())
return 1;
vector<int> d;
for(int i=0;i<v[u].size();i++)
{
d.push_back(dfs(v[u][i]));
}
sort(d.begin(),d.end());
int c=v[u].size()*t;
if(c%100)
{
c=c/100+1;
}
else
c=c/100;
int ans=0;
for(int i=0;i<c;i++)
{
ans+=d[i];
}
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
while(cin>>n>>t)
{
if(!n&&!t)
{
break;
}
for(int i=0;i<maxn;i++)
{
v[i].clear();
}
for(int i=1;i<=n;i++)
{
int a;
cin>>a;
v[a].push_back(i);
}
cout<< dfs(0) <<endl;
}
return 0;
}