• 黑白树


     

     题解:设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
  • 相关阅读:
    字典的增删改查
    基础数据类型
    Linux程序优化实践
    Linuxt性能调优指南
    【MySQL】Percona Toolkits工具介绍及使用
    【MySQL】如何构建高性能MySQL系统?
    【MySQL】Event使用案例
    【MySQL】事件调度器 (Event Scheduler)
    【MySQL】mydumper工具介绍
    spu与sku的含义
  • 原文地址:https://www.cnblogs.com/rlddd/p/15040117.html
Copyright © 2020-2023  润新知