点此看题面

大致题意: 有\(N\)名忍者,每名忍者有三个属性:上司\(B_i\),薪水\(C_i\)和领导力\(L_i\)。你要选择一个忍者作为管理者,然后在所有被他管理的忍者中选择若干名忍者,使薪水总和不超过预算\(M\)。现让你最大化被派遣的忍者总数乘以管理者的领导力水平。

关于左偏树

这道题是一道比较裸的左偏树板子题。

左偏树,主要用途是实现堆的合并,在这一类的题目中还是比较实用的。

大致思路

如果你会左偏树,那么这题就是一道水题。

首先考虑遍历题目中给出的树,然后对每一个节点开一个大根堆,每次把超过预算的多余部分弹出,更新\(ans\)之后再与父亲的堆进行合并。

一个细节就是当前节点可能会被弹出,所以我们要用\(Top_x\)来记录当前节点堆的堆顶,然后对\(Top_x\)进行操作。

代码

#include<bits/stdc++.h>
#define N 100000
#define swap(x,y) (x^=y^=x^=y)
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
#define Gmax(x,y) (x<(y)&&(x=(y)))
#define LL long long
using namespace std;
int n,m,ee=0,lnk[N+5],Top[N+5],cnt[N+5],Cost[N+5],Val[N+5];LL ans=0,tot[N+5];
struct edge
{
int to,nxt;
}e[N+5];
class FIO
{
private:
#define Fsize 100000
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,Fsize,stdin),A==B)?EOF:*A++)
#define pc(ch) (void)(putchar(ch))
int Top,FoutSize;char ch,*A,*B,Fin[Fsize],Fout[Fsize],Stack[Fsize];
public:
inline void read(int &x) {x=0;while(!isdigit(ch=tc()));while(x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));}
inline void write(LL x) {if(!x) return pc('0');while(x) Stack[++Top]=x%10+48,x/=10;while(Top) pc(Stack[Top--]);}
}F;
class Class_LeftistTree//左偏树模板
{
private:
struct Tree
{
int Val,Dis,Exist,Father,Son[2];
Tree(int x=0):Val(x){Dis=Father=Son[0]=Son[1]=0,Exist=1;}
}node[N+5];
inline int Merge(int x,int y)
{
if(!x||!y) return x+y;
if(node[x].Val<node[y].Val) swap(x,y);
if(node[node[x].Son[1]=Merge(node[x].Son[1],y)].Father=x,node[node[x].Son[0]].Dis<node[node[x].Son[1]].Dis) swap(node[x].Son[0],node[x].Son[1]);
return node[x].Dis=node[node[x].Son[1]].Dis+1,x;
}
inline int TopPos(int x) {while(node[x].Father) x=node[x].Father;return x;}
public:
Class_LeftistTree() {node[0].Dis=-1,node[0].Exist=0;}
inline void Init(int n,int *data) {for(register int i=1;i<=n;++i) node[i]=Tree(data[i]);}
inline void Union(int x,int y) {if((x=TopPos(x))^(y=TopPos(y))&&node[x].Exist&&node[y].Exist) Merge(x,y);}
inline int PopTop(int x) {return node[x=TopPos(x)].Val=node[x].Dis=-1,node[x].Exist=0,node[node[x].Son[0]].Father=node[node[x].Son[1]].Father=0,Merge(node[x].Son[0],node[x].Son[1]);}
inline int TopVal(int x) {return node[TopPos(x)].Val;}
}LeftistTree;
inline void dfs(int x)//遍历
{
register int i;
for(i=lnk[Top[x]=x],tot[x]=Cost[x],cnt[x]=1;i;i=e[i].nxt) dfs(e[i].to),LeftistTree.Union(x,Top[e[i].to]),tot[x]+=tot[e[i].to],cnt[x]+=cnt[e[i].to];//先遍历子节点,然后从子节点更新信息
while(tot[x]>m) tot[x]-=LeftistTree.TopVal(Top[x]),--cnt[x],Top[x]=LeftistTree.PopTop(Top[x]);//弹出多余的元素
Gmax(ans,1LL*Val[x]*cnt[x]);//更新ans
}
int main()
{
register int i,x,rt;
for(F.read(n),F.read(m),i=1;i<=n;++i) F.read(x),F.read(Cost[i]),F.read(Val[i]),(x?add(x,i):rt=i);
return LeftistTree.Init(n,Cost),dfs(rt),F.write(ans),0;
}

【BZOJ2809】[APIO2012] dispatching(左偏树例题)的更多相关文章

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

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

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

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

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

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

  4. [Apio2012]dispatching 左偏树

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

  5. [Apio2012]dispatching 左偏树做法

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

  6. APIO2012 派遣dispatching | 左偏树

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

  7. BZOJ2809 dispatching(左偏树)

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

  8. [APIO2012]派遣 左偏树

    P1552 [APIO2012]派遣 题面 考虑枚举每个节点作为管理者,计算所获得的满意程度以更新答案.对于每个节点的计算,贪心,维护一个大根堆,每次弹出薪水最大的人.这里注意,一旦一个人被弹出,那么 ...

  9. 洛谷P1552 [APIO2012] 派遣 [左偏树,树形DP]

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

随机推荐

  1. 40.QT-QPropertyAnimationdong和QParallelAnimationGroup动画实现

    简述:QPropertyAnimation (动画类,用来向QObject对象添加动画) 该类的继承框图如下所示: 1.QAbstractAnimation(所有动画的抽象基类) 该抽象类为QProp ...

  2. 历年NOIP真题总结

    前言:最近把历年的NOIP真题肝了一遍(还有3个紫题先咕掉了),主要是到1998年的提高组的题.把题目的做题简要思路搁在这儿,一个是为了考前翻一翻,想想自己的哪些思路要梳理的什么什么的,反正怎么说呢, ...

  3. Python中print()函数不换行的方法

    一.让print()函数不换行 在Python中,print()函数默认是换行的.但是,在很多情况下,我们需要不换行的输出(比如在算法竞赛中).那么,在Python中如何做到这一点呢? 其实很简单.只 ...

  4. nodejs安装及使用步骤详解

    就一段小小的时间不用,就忘得差不多了,果然好记性不如乱笔头. 1.必须要安装node环境(建议装在C盘,这是一个系统盘)+安装mongoose数据库  +Robot 3T之于mongodb就相当于so ...

  5. A. The Fair Nut and Elevator(暴力)

    time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...

  6. python大战机器学习——数据预处理

    数据预处理的常用流程: 1)去除唯一属性 2)处理缺失值 3)属性编码 4)数据标准化.正则化 5)特征选择 6)主成分分析 1.去除唯一属性 如id属性,是唯一属性,直接去除就好 2.处理缺失值 ( ...

  7. ResourceBundle 读取properties文件中文乱码

    1.确认properties文件是什么编码格式,并确认文件在该格式下中文是正常显示的2.读取时候,进行转一层,先用ISO-8859-1读取字节流,然后根据properties的文件格式进行new St ...

  8. 使用C#连接 MyCat 链接串

    所属专栏: mycat的安装部署以及监控和运维    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u014180504/article/detai ...

  9. D. Beautiful numbers

    题目链接:http://codeforces.com/problemset/problem/55/D D. Beautiful numbers time limit per test 4 second ...

  10. 关于Function.prototype.apply.call的一些补充

    宿主对象,在javascript中有三类对象,本地对象,内置对象和宿主对象.其他两类暂且不提,宿主对象是指什么呢(DOM BOM),控制台对象是文档对象模型的扩展,也被认为是宿主对象.那么,它们有什么 ...