zoukankan      html  css  js  c++  java
  • [CodeForces1059E] Split the Tree

    树形DP.

    用倍增处理出来每个点往上能延伸出去的最远路径,nlogn

    对于每个节点,如果它能被后代使用过的点覆盖,就直接覆盖,这个点就不使用,否则就ans++,让传的Max改成dp[x]

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const int N=100005;
    int n,a[N],fa[N][20],f[N],head[N],to[N<<1],nxt[N<<1],ecnt,ans,L;
    inline void add(int bg,int ed) {
        nxt[++ecnt]=head[bg];to[ecnt]=ed;head[bg]=ecnt;
    }
    ll S,v[N][20];
    void dfs(int x) {
        for(int i=head[x];i;i=nxt[i]) 
            if(to[i]!=fa[x][0]) fa[to[i]][0]=x,v[to[i]][0]=a[x],dfs(to[i]);
    }
    int Dfs(int x) {
        int Max=0;
        for(int i=head[x];i;i=nxt[i]) if(to[i]!=fa[x][0]) Max=max(Max,Dfs(to[i]));
        if(!Max) {
            ans++;
            return f[x]-1;
        }
        return Max-1;
    }
    int main() {
        cin>>n>>L>>S;
        for(int i=1;i<=n;i++) {scanf("%d",&a[i]);if(a[i]>S) return puts("-1"),0;}
        for(int i=1,x;i<n;i++)     scanf("%d",&x),add(x,i+1),add(i+1,x);
        dfs(1);
    
        for(int i=1;(1<<i)<=L;i++) {
            for(int j=1;j<=n;j++) {
                fa[j][i]=fa[fa[j][i-1]][i-1];
                v[j][i]=v[fa[j][i-1]][i-1]+v[j][i-1];
            }
        }
        for(int i=1;i<=n;i++) {
            ll sum=a[i];int now=i;f[i]=1;
            for(int j=19;~j&&sum<=S;j--) {
                if(fa[now][j]&&sum+v[now][j]<=S&&f[i]+(1<<j)<=L) 
                                sum+=v[now][j],f[i]+=1<<j,now=fa[now][j];
            }
        }
        Dfs(1);
        cout<<ans;
        return 0;
    }    
    Split the Tree
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    Spring 注解@Transactional
    数据库中为什么要建立视图,它有什么好处?
    类、抽象类与接口的区别
    Comparable和Comparator的区别?
    jetty安装
    python 命令行参数sys.argv
    python--用户认证登录实现
    python--查询员工信息
    python基础
    python学习之路---编程风格规范
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9770453.html
Copyright © 2011-2022 走看看