【每日一题】黑白树(思维+dfs)

黑白树

https://ac.nowcoder.com/acm/problem/13249

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;
}
全部评论

相关推荐

拒绝无效加班的小师弟很中意你:求职意向没有,年龄、课程冗余信息可以删掉,需要提升项目经历。排版需要修改。
点赞 评论 收藏
分享
10-09 22:05
666 C++
找到工作就狠狠玩CSGO:报联合国演讲,报电子烟设计与制造
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务