zoukankan      html  css  js  c++  java
  • Codeforces Round #514 (Div. 2) E. Split the Tree(倍增+贪心)

    https://codeforces.com/contest/1059/problem/E

    题意

    给出一棵树,每个点都有一个权值,要求你找出最少条链,保证每个点都属于一条链,而且每条链不超过L个点 和 每条链的权值和不超过S

    题解

    • 对于儿子来说,父亲节点只有一个,所以没有决策点。可以从下往上处理出,每个节点最远能爬到那个节点(过程就是倍增)
    • 然后从下往上贪 (选择往上走的远的子节点)
    #include<bits/stdc++.h>
    #define ll long long
    #define pb push_back
    #define N 100005
    using namespace std;
    vector<int>g[N];
    int n,l,i,v,u,ans,f[N][25],d[N],top[N],pre[N];
    ll s,w[N],sum[N];
    
    void dfs(int u,int fa){
        sum[u]=sum[fa]+w[u];
        d[u]=d[fa]+1;
        f[u][0]=fa;
        for(i=1;i<=20;i++)f[u][i]=f[f[u][i-1]][i-1];
        top[u]=u;
        
        int D=l;
        for(i=20;i>=0;i--){
            int v=f[top[u]][i];
            if(v==0||(1<<i)>=D||sum[u]-sum[f[v][0]]>s)continue;
            D-=(1<<i);
            top[u]=v;
        }
        for(int i=0;i<g[u].size();i++){
            int v=g[u][i];dfs(v,u);
        }
    }
    
    void dfs2(int u){
       int bt=0;
       for(int i=0;i<g[u].size();i++){
          int v=g[u][i];
          dfs2(v);
          if(pre[v]==v)continue;
          if(!bt||d[bt]>d[pre[v]])bt=pre[v];
       }
       if(!bt){ans++;bt=top[u];}
       pre[u]=bt;
    }
    int main(){
       cin>>n>>l>>s;
       for(i=1;i<=n;i++){
           scanf("%lld",&w[i]);
           if(w[i]>s){cout<<-1;return 0;}
       }
       for(i=2;i<=n;i++){
           scanf("%d",&v);
           g[v].pb(i);
       }
       ans=0;
       dfs(1,0);
       dfs2(1);
       cout<<ans<<endl;
    }
    
  • 相关阅读:
    A
    MongoDB小结17
    MongoDB小结16
    金蝶无法生成下推发票
    MongoDB小结15
    MongoDB小结14
    MongoDB小结13
    MongoDB小结12
    MongoDB小结11
    MongoDB小结10
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/9971248.html
Copyright © 2011-2022 走看看