黑白树
黑白树
https://ac.nowcoder.com/acm/problem/13249
逆序(从根)操作,即可选黑点,但代码依然是从叶子操作
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int const INF=0x3f3f3f3f;
int const N=1e5+7;
int const M=1e5+7;
struct node{
int a,len,next;
}e[M<<1];
int head[N],cnt;
void add(int x,int y,int len){
e[++cnt].a =y;
e[cnt].len =len;
e[cnt].next =head[x];
head[x]=cnt;
}
int n,ans;
int w[N],vis[N]; //w[i]表示i点以下(包括i点)到i点剩余权值的最大值
ll f[N]; //f[i]表示上一个涂黑的点到i点时,剩余的权值
void dfs(int s){
for(int i=head[s];i!=-1;i=e[i].next ){
if(vis[e[i].a ]) continue;
vis[e[i].a ]=1;
dfs(e[i].a );
w[s]=max(w[s],w[e[i].a]-1);
f[s]=max(f[s],f[e[i].a ]-1);
}
if(!f[s]) f[s]=w[s],ans++;
}
int main(){
cin >> n ;
memset(head,-1,sizeof head);
memset(e,-1,sizeof e);
for(int i=2;i<=n;++i){
int a;cin >> a;
add(i,a,0);add(a,i,0);
}
for(int i=1;i<=n;++i){
cin >> w[i];
}
vis[1]=1;
dfs(1);
cout << ans;
return 0;
} 
