Solution
emm昨天看了但是没有写出来,因为不会处理回溯过程中的更有利涂黑的情况。
题解很巧妙,没想到可以用另外一个数组d来记录可以最多涂黑到哪个点,当数组d为0时就代表需要多操作一次,而这个更新操作次数正是这道题的灵魂所在。
简单来说就是:
更新回溯过程中最远可到达的距离
更新回溯过程中无须操作就可到达的距离
而当为0时就代表需要多花一次操作次数。
Code
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define lowbit(x) (x&(-x))
using namespace std;
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;}
void put1(){ puts("YES") ;}void put2(){ puts("NO") ;}void put3(){ puts("-1"); }
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a =
(a*a)%p;b >>= 1;}return ans%p;}
const ull base=2333; const ull pp=19260811; const ull ppp=999998639;
const int manx=1e5+5;
const int mo=998244353;
vector<ll>g[manx];
ll w[manx],d[manx];
ll ans=0;
void dfs(ll u,ll pre){
for(auto v:g[u]){
if(v==pre) continue;
dfs(v,u);
w[u]=max(w[u],w[v]-1);
d[u]=max(d[u],d[v]-1);
}
if(!d[u]) ++ans,d[u]=w[u];
}
int main(){
ll n=read();
for(int i=2;i<=n;i++){
ll f=read();
g[f].pb(i);
}
for(int i=1;i<=n;i++) w[i]=read();
dfs(1,0);
printf("%lld",ans);
return 0;
}

京公网安备 11010502036488号