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

Input

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

Output

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

Sample Input
5 4
0 3 3
1 3 5
2 2 2
1 2 4
2 3 1

Sample Output6

Hint

如果我们选择编号为 1的忍者作为管理者并且派遣第三个和第四个忍者,薪水总和为 4,没有超过总预算                         4。因为派遣了                              2   个忍者并且管理者的领导力为      3,

用户的满意度为 2      ,是可以得到的用户满意度的最大值。

题解:左偏树板题;

dfs搜索时,如果超过了薪水总量,就去掉堆顶元素(最大元素),更新ans的值即可;

参考代码:

 #include<bits/stdc++.h>
using namespace std;
#define clr(a,val) memset(a,val,sizeof (a))
#define fi first
#define se second
#define pb push_back
#define eps 1e-6
typedef long long ll;
const int INF=0x3f3f3f3f;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
const int N=1e5+;
struct edge{
int to,next;
} a[N];
int head[N],cnt;
int n,Master,ls[N],rs[N],dis[N];
ll m,C[N],L[N],sum[N],sz[N],ans; void addedge(int u,int v)
{
a[++cnt]=(edge){v,head[u]};
head[u]=cnt;
}
int Merge(int A,int B)//合并树
{
if (!A||!B) return A+B;
if(C[A]<C[B]) swap(A,B);
rs[A]=Merge(rs[A],B);
if(dis[ls[A]]<dis[rs[A]]) swap(ls[A],rs[A]);
dis[A]=dis[rs[A]]+;
return A;
}
int Delete(int A)//去除堆顶
{
return Merge(ls[A],rs[A]);
}
int find(int x){if(f[x]!=x) f[x]=find(f[x]);return f[x];}
int pop(int x)
{
f[x]=Merge(ls[x],rs[x]);
f[f[x]]=f[x];
ls[x]=rs[x]=dis[x]=;
return f[x];
}
int dfs(int u)
{
int A=u,B;
sum[u]=C[u]; sz[u]=;
for(int e=head[u];e;e=a[e].next)
{
int v=a[e].to;
B=dfs(v);
A=Merge(A,B);
sum[u]+=sum[v];sz[u]+=sz[v];
}
while(sum[u]>m)//超过要求的薪水
{
sum[u]-=C[A];sz[u]--;//去掉所需薪水最大的Master
A=Delete(A);
}
ans=max(ans,L[u]*sz[u]);
return A;
}
int main()
{
n=read();m=read();
for(int i=;i<=n;i++)
{
int u=read();
C[i]=read();L[i]=read();
if(!u) Master=i;
else addedge(u,i);
}
dfs(Master);
printf("%lld",ans);
return ;
}

BZOJ2809 dispatching(左偏树)的更多相关文章

  1. 【bzoj2809】[Apio2012]dispatching 左偏树

    2016-05-31  15:56:57 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2809 直观的思想是当领导力确定时,尽量选择薪水少的- ...

  2. bzoj2809 [Apio2012]dispatching(左偏树)

    [Apio2012]dispatching Description 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 M ...

  3. bzoj2809 [Apio2012]dispatching——左偏树(可并堆)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2809 思路有点暴力和贪心,就是 dfs 枚举每个点作为管理者: 当然它的子树中派遣出去的忍者 ...

  4. APIO2012 派遣dispatching | 左偏树

    题目链接:戳我 就是尽可能地选取排名小的,加起来就可以了.然后我们考虑利用一个大根堆,一个一个合并,如果超过派遣的钱,我们就把费用最大的那个忍者丢出队列. 左偏树,作为一个十分优秀的可并堆,我们这道题 ...

  5. [Apio2012]dispatching 左偏树

    题目描述 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个上级.为保密,同时增 ...

  6. [Apio2012]dispatching 左偏树做法

    http://codevs.cn/problem/1763/ 维护子树大根堆,当子树薪水和>m时,删除最贵的点 #include<cstdio> #include<iostre ...

  7. 【BZOJ2809】【APIO2012】Dispatching(左偏树)

    题面 Description 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个 ...

  8. [BZOJ2809][Apio2012]dispatching(左偏树)

    首先对于一个节点以及它的子树,它的最优方案显然是子树下选最小的几个 用左偏树维护出每棵子树最优方案的节点,记录答案 然后它的这棵树可以向上转移给父节点,将所有子节点的左偏树合并再维护就是父节点的最优方 ...

  9. 【BZOJ2809】[APIO2012] dispatching(左偏树例题)

    点此看题面 大致题意: 有\(N\)名忍者,每名忍者有三个属性:上司\(B_i\),薪水\(C_i\)和领导力\(L_i\).你要选择一个忍者作为管理者,然后在所有被他管理的忍者中选择若干名忍者,使薪 ...

随机推荐

  1. Java基础:8种基本数据类型,取值范围和储存字节说明。

    Java中,一共有8种基本数据类型: 4种整数型:int,short,long,byte. 2种浮点型:float,double. 1种字符类型:char. 1种表示真值的类型:boolean. [S ...

  2. Salesforce学习之路(十一)Aura组件属性<aura:attribute />

    1. <aura:attribute />语法 Aura组件属性类似与Apex中类的成员变量(或者说Java中类的成员变量).他们是组件在特定的实例上设置的类型化字段,可以使用表达式语法从 ...

  3. 关于虚拟机克隆之后IP重新设置

    由于要搭建一套环境,本来搭建好的后来搞崩了,因为之前的虚拟机没有克隆过以及创建快照,所以今天就重新创建一套环境创建虚拟机快照,以及要解决克隆之后的IP重新设置问题. 1.查看本机orcl IP:[ro ...

  4. 【Luogu P2002&P2341】消息扩散/受欢迎的奶牛

    Luogu P2002 Luogu P2341 使用强连通分量算法缩点 第一题统计入度为0的个数强连通分量数. 第二题的答案为当且仅当仅有一个强连通分量的出度为0时该强连通分量的节点数,原因如下:若一 ...

  5. ctf比赛linux文件监控和恢复shell

    之前参加ctf比赛时候临时写的,有很多不足,不过可以用,就贴出来分享给大家,希望对大家有帮助. 脚本一:记录当前目录情况 #!/bin/bashfunction getdir(){    for el ...

  6. java多线程的wait、notify/notifyAll区别

    1.wait().notify/notifyAll() 方法是Object的本地final方法,无法被重写.   2.wait()使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized ...

  7. MySQL 格式化时间 成字符串

    创建个表: CREATE TABLE `x02基本信息` ( `ID` varchar(32) NOT NULL COMMENT '系统内记录的唯一标识,供系统内部使用.', `名称` varchar ...

  8. node_export 安装

    目录 安装部署 环境准备 下载安装 启动测试 安装部署 环境准备 主机名 角色 IP 系统版本 内核版本 es01.k8s.com node01 10.0.20.11 CentOS 7.5 5.1.4 ...

  9. 单核苷酸多态性SNP(single nucleotide polymorphism)

    定义 主要指基因组水平上由单个核苷酸的变异所引起的 DNA 序列多态性. 在基因组水平上由单个核苷酸的变异所引起的DNA序列多态性.即:在不同个体的同一条染色体或同一位点的核苷酸序列中,绝大多数核苷酸 ...

  10. 安装nvm管理多版本nodejs

    1.简介(什么是nvm) Node Version Manager(node版本管理器),用它在机器上安装并维护管理多个Node的版本 2.nvm临时切换(临时切换版本,只在当前终端内有效,新开终端无 ...