题目:就是问一次牌子最多能遍历多少个不同的叶子节点。
思路:假如牌子会落在当前位置的某颗子树上的一个叶子,那么就需要先统计好其他子树上可以到达并且返回的叶子节点数,然后枚举完所有叶子的可能即可。
(如果牌子在两个叶子能上升到达同一个节点,那么他们最高到达的节点是一样的)
#include <cstdio>
#include <string.h>
#include <vector>
using namespace std;
#define MAX 1000100
int a[MAX];
int b[MAX];
int n,k;
vector<int> e[MAX];
void dfs(int u){
if(e[u].size()==0){
a[u]=1;
b[u]=k;
return ;
}
for(int i=0;i<e[u].size();i++){
int to=e[u][i];
dfs(to);
if(b[to]>=1){
a[u]+=a[to];
}
b[u]=max(b[u],b[to]-1);
}
}
int fin=0;
void solve(int u,int ans){
if(e[u].size()==0){
ans++;
fin=max(fin,ans);
}
for(int i=0;i<e[u].size();i++){
int to=e[u][i];
int sum=a[u];
if(b[to]>=1)
solve(to,ans+a[u]-a[to]);
else
solve(to,ans+a[u]);
}
}
int main(){
scanf("%d%d",&n,&k);
int x;
for(int i=2;i<= n;i++){
scanf("%d",&x);
e[x].push_back(i);
}
dfs(1);
solve(1,0);
printf("%d\n",fin);
return 0;
}