zoukankan      html  css  js  c++  java
  • BZOJ2809: [Apio2012]dispatching

    [Submit][Status][Discuss]

    Description

    在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿。在这个帮派里,有一名忍者被称之为 Master。除了 Master以外,每名忍者都有且仅有一个上级。为保密,同时增强忍者们的领导力,所有与他们工作相关的指令总是由上级发送给他的直接下属,而不允许通过其他的方式发送。现在你要招募一批忍者,并把它们派遣给顾客。你需要为每个被派遣的忍者 支付一定的薪水,同时使得支付的薪水总额不超过你的预算。另外,为了发送指令,你需要选择一名忍者作为管理者,要求这个管理者可以向所有被派遣的忍者 发送指令,在发送指令时,任何忍者(不管是否被派遣)都可以作为消息的传递 人。管理者自己可以被派遣,也可以不被派遣。当然,如果管理者没有被排遣,就不需要支付管理者的薪水。你的目标是在预算内使顾客的满意度最大。这里定义顾客的满意度为派遣的忍者总数乘以管理者的领导力水平,其中每个忍者的领导力水平也是一定的。写一个程序,给定每一个忍者 i的上级 Bi,薪水Ci,领导力L i,以及支付给忍者们的薪水总预算 M,输出在预算内满足上述要求时顾客满意度的最大值。
    1  ≤N ≤ 100,000 忍者的个数;
    1  ≤M ≤ 1,000,000,000 薪水总预算; 
    0  ≤Bi < i  忍者的上级的编号;
    1  ≤Ci ≤ M                     忍者的薪水;
    1  ≤Li ≤ 1,000,000,000             忍者的领导力水平。

    Input

    从标准输入读入数据。
     
    第一行包含两个整数 N M,其中 N表示忍者的个数,M表示薪水的总预算。
     
    接下来 N行描述忍者们的上级、薪水以及领导力。其中的第 i 行包含三个整 Bi , C i , L i分别表示第i个忍者的上级,薪水以及领导力。Master满足B i = 0并且每一个忍者的老板的编号一定小于自己的编号 Bi < i

    Output

    输出一个数,表示在预算内顾客的满意度的最大值。

    Sample Input

    5 4
    0 3 3
    1 3 5
    2 2 2
    1 2 4
    2 3 1

    Sample Output

    6

    思路{

      左偏树懂了,然而通过这道题还是可以发现并不熟练。

      首先是很容易想到采用树形DP的方法向上合并解。

      故想到使用可并堆。但是是大根堆还是小根堆?

      若小根堆(我最开始写的),应当顺序统计,直到和大于m为止,其他全部pop

      看出,这样的复杂度比较高。(然而我没有TLEWA了。。。。。。。。)

      大根堆的话,弹出元素直到元素和<=m.比较容易实现。

      在DFS的过程中,为了防止变量之间的冲突,

      还要设一个数组表示当前点所属的堆。(可能我就WA在这里吧。。。。)

      为了在COGS上速度超过PZ,我竟然使用了读入优化。。。。。。

      

    }

    #include<bits/stdc++.h>
    #define RG register
    #define il inline 
    #define N 100010
    #define LL long long
    using namespace std;
    int v[N],l[N],r[N],d[N],L[N],n,head[N],tot,BL[N],sz[N];LL sum[N];
    struct ed{int nxt,to;}e[N];int m;LL ans;
    void add(RG int u,RG int v){e[tot].nxt=head[u];e[tot].to=v;head[u]=tot++;}
    il int merge(RG int x,RG int y){
      if(!x||!y)return x+y;
      if(v[x]<v[y])swap(x,y);
      r[x]=merge(r[x],y);
      if(d[r[x]]>d[l[x]])swap(r[x],l[x]);
      d[x]=d[r[x]]+1;return x;
    }
    il int getint(){
        int w=0;bool q=0;
        char c=getchar();
        while((c>'9'||c<'0')&&c!='-') c=getchar();
        if(c=='-') c=getchar(),q=1;
        while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
        return q?-w:w;
    }
    il void dfs(int u){BL[u]=u;sum[u]=v[u];sz[u]=1;
      for(RG int i=head[u];i!=-1;i=e[i].nxt){
          RG int v=e[i].to;
          dfs(v);sum[u]+=sum[v];
          sz[u]+=sz[v];
          BL[u]=merge(BL[u],BL[v]);
      }while(sum[u]>m&&sz[u]){
        sum[u]-=v[BL[u]];
        BL[u]=merge(r[BL[u]],l[BL[u]]);
        sz[u]--;
      }ans=max(ans,(LL)sz[u]*L[u]);
    }
    int main(){
      freopen("dispatching.in","r",stdin);
      freopen("dispatching.out","w",stdout);
      memset(head,-1,sizeof(head));
      n=getint(),m=getint();
      for(RG int i=1;i<=n;++i){int ytk;
        ytk=getint(),v[i]=getint(),L[i]=getint();
        add(ytk,i);
      }dfs(1);printf("%lld",ans);
      return 0;
    }
    

      

     
     
     
  • 相关阅读:
    ASP.NET应用程序与页面生命周期
    Git源码管控规范
    redis cluster
    jwt token and shiro
    openapi and light-4j
    ps 证件照制作
    js eval 动态内容生成
    pdnovel 看书 读书 听书
    crawler 使用jQuery风格实现
    websocket聊天体验(二)
  • 原文地址:https://www.cnblogs.com/zzmmm/p/7224151.html
Copyright © 2011-2022 走看看