The code is divided into recursive and non-recursive versions.
The recursive version is a direct reference to the purple book.
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=100000+5;
int n,T;
vector<int> sons[maxn];
int dp(int u) {
if (sons[u].empty()) return 1;
vector<int> d;
for (int i=0; i<sons[u].size(); i++)
d.push_back(dp(sons[u][i]));
sort(d.begin(), d.end());
int c = (sons[u].size()*T-1)/100 + 1;
int ans = 0;
for (int i=0; i<c; i++)
ans+=d[i];
return ans;
}
int main()
{
int boss;
while(scanf("%d%d", &n, &T)==2 && n) {
for (int i=0; i<=n; i++)
sons[i].clear();
for (int i=1; i<=n; i++) {
scanf("%d", &boss);
sons[boss].push_back(i);
}
cout<<dp(0)<<endl;
}
return 0;
}
A few points to note:
1) c=(KT-1)/100+1 is the smallest integer representing not less than KT/100. For example, KT=33, then KT/100=0, c=1. KT=1, KT/100=0, c=1.
So why not use KT/100+1 directly? Because if KT/100 is exactly 1, then c=2, but in fact c should be equal to 1.
2) When initializing sons[], i starts from 0, because the boss's sons is also initialized to 0. But when assigning a value to sons[], i starts from 1, such as 0, 3, 5, which means that the boss of employee 1 is 0, the boss of employee 2 is 3, and the boss of employee 3 is 5.
3) Because the title says that the minimum required employee signatures are required, we need to sort the d array to find the first c smallest values.
The non-recursive version was written by me, implemented using stacks. This code may not be optimal because the parent[] array is also added, but it is accepted anyway. If you have a better one, please leave a message.
#include<iostream>
#include<vector>
#include<algorithm>
#include <stack>
using namespace std;
const int maxn=100000+5;
int n,T;
vector<int> sons[maxn];
int parent[maxn] = {0};
stack<int> s;
int ans[maxn] = {0};
int dp_non_recursion() {
vector<int> d;
//从老板开始,依次将儿子压栈
s.push(0);
for (int i=0; i<n; i++)
for (int j=0; j<sons[i].size(); j++)
s.push(sons[i][j]);
while(!s.empty()) {
d.clear();
int t = s.top();
s.pop();
if (sons[t].size()==0)
ans[t]=1;
else{
for (int i=0; i<sons[t].size(); i++) {
d.push_back(ans[sons[t][i]]);
}
sort(d.begin(), d.end());
int c = (sons[t].size()*T-1)/100 + 1;
for (int i=0; i<c; i++)
ans[t]+=d[i];
}
}
return ans[0];
}
int main()
{
int boss;
while(scanf("%d%d", &n, &T)==2 && n) {
for (int i=0; i<=n; i++) {
sons[i].clear();
ans[i]=0;
}
for (int i=1; i<=n; i++) {
scanf("%d", &boss);
parent[i]=boss;
sons[boss].push_back(i);
}
cout<<dp_non_recursion()<<endl;
}
return 0;
}
Note that whether recursive or non-recursive, we don't need to use vis[], because each node is processed exactly once, and there is no repeated visit.