• 黑白树


     

     题解:设k[ x ]为节点x以及它的子树中的点能往上走的最长距离,即 k[ x ] = max ( k[ x ] , k[ v ] -1 )  ,v是x的儿子,设f [ x ] 为选择了节点后还能往上走的距离, f[ x ] = max( f[ x ] , f[ v ] -1 ) , 当 f [ x ] = 0 时,答案加一,且 f [ x ] = k [ x ] 。

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=1e5+50;
    
    int n,fa[maxn],k[maxn],f[maxn],ans;
    int fir[maxn],nex[maxn<<1],to[maxn<<1],ecnt;
    
    void add(int u,int v){
        nex[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v;
    }
    
    void dfs(int x){
        for(int e=fir[x];e;e=nex[e]){
            int v=to[e];
            if(v==fa[x]) continue;
            dfs(v);
            k[x]=max(k[x],k[v]-1);
            f[x]=max(f[x],f[v]-1);
        }
        if(!f[x]){
            ans++;
            f[x]=k[x];
        }
    }
    
    template<typename T>void inline read(T &aa){
        ll ff=1;char cc=getchar();aa=0;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc<='9'&&cc>='0') aa=aa*10+cc-48,cc=getchar();
        aa*=ff;
    }
    
    int main(){
        cin>>n;
        for(int i=2;i<=n;i++){
            read(fa[i]);
            add(fa[i],i);add(i,fa[i]);
        }
        for(int i=1;i<=n;i++) read(k[i]);
        dfs(1);
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    团队项目-选题报告
    第一次结对编程作业
    第一次个人编程作业
    第一次软工作业
    antd form表单数组对象格式
    antd form表单验证失去焦点时验证和重置验证状态
    fetch请求
    typescript类装饰器
    typescript泛型
    浮点数问题
  • 原文地址:https://www.cnblogs.com/rlddd/p/15040117.html
Copyright © 2020-2023  润新知