APIO 2012 派遣(可并堆)
APIO 2012 派遣(可并堆)
给定一棵N个点的树和M,每个点有两个权值ai,bi,每次可以选择一个点x,然后在这个点的子树中选若干点(可以不选自己),使得这些点的\(\sum b_i<=M\)。收益为ax*选出的点个数。求最大收益。
对每个点维护一个大根堆即可~~
#include <cstdio>
using namespace std;
typedef long long LL;
const LL maxn=2e5+5;
void swap(LL &x, LL &y){ LL t=x; x=y; y=t; }
LL max(LL x, LL y){ return x<y?y:x; }
struct Edge{
LL to, nxt;
}e[maxn];
LL cnte, fir[maxn], ans;
void addedge(LL x, LL y){
Edge &ed=e[++cnte];
ed.to=y; ed.nxt=fir[x]; fir[x]=cnte; }
LL n, M, rt, b[maxn], v[maxn], sum[maxn], cnt[maxn];
//要维护关于薪水b的大根堆 sum表示堆内所有b的和 cnt表示堆内有多少点
struct LHeap{
LL l, r, dis, fa;
}h[maxn];
LL find(LL x){ return h[x].fa==x?x:find(h[x].fa); }
LL merge(LL x, LL y){ //把x和y为根的树合并
if (!x||!y) return x+y;
if (b[x]<b[y]) swap(x, y);
LL &lx=h[x].l, &rx=h[x].r;
rx=merge(rx, y); h[rx].fa=x; //把右子树和y树合并
if (h[lx].dis<h[rx].dis) swap(lx, rx);
h[x].dis=h[rx].dis+1;
sum[x]=sum[lx]+sum[rx]+b[x];
cnt[x]=cnt[lx]+cnt[rx]+1;
return x; //返回根的编号
}
LL del(LL x){ //删除树x的根结点,返回新根的编号
LL lx=h[x].l, rx=h[x].r;
h[lx].fa=lx; h[rx].fa=rx;
return merge(lx, rx);
}
LL dfs(LL x){ //返回合并后大根堆的根结点编号 刚开始的时候,x的堆根结点的编号就是x
LL u=x;
for (LL i=fir[x]; i; i=e[i].nxt)
x=merge(dfs(e[i].to), x); //不停合并子树的堆
while (sum[x]>M) x=del(x); //使得当前的堆的sumb<=M
ans=max(ans, v[u]*cnt[x]);
return x;
}
int main(){
scanf("%lld%lld", &n, &M); LL t;
for (LL i=1; i<=n; ++i){
scanf("%lld%lld%lld", &t, &b[i], &v[i]);
if (t) addedge(t, i); else rt=i;
h[i].fa=i; sum[i]=b[i]; cnt[i]=1;
}
dfs(rt); printf("%lld\n", ans);
return 0;
}
APIO 2012 派遣(可并堆)的更多相关文章
- [APIO 2012]派遣
Description 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿. 在这个帮派里,有一名忍者被称之为Master.除了Master以外,每名忍者都有且仅有一个上级.为 ...
- 解题:APIO 2012 派遣
题面 以报酬为标准维护一个大根堆,从根节点往上合并,每次踢掉若干人直到花费合法后更新答案 #include<cstdio> #include<cstring> #include ...
- [APIO2012]派遣 可并堆
Background 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿. Description 在这个帮派里,有一名忍者被称之为Master.除了Master以外,每名忍者 ...
- 【BZOJ 2809】【APIO 2012】dispatching
昨天晚上zyf神犇问我的题,虽然我太弱参加不了APIO但也做一做吧. 用小数据拍了无数次总是查不出错来,交上去就WA,后来用国内数据测发现是主席树上区间相减的值没有用long long存,小数据真是没 ...
- 洛谷P3620 [APIO/CTSC 2007] 数据备份 [堆,贪心,差分]
题目传送门 题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽 ...
- BZOJ 2809 APIO 2012 dispatching 平衡树启示式合并
题目大意:给出一棵树,每个节点有两个值,各自是这个忍者的薪水和忍者的领导力.客户的惬意程度是这个点的领导力乘可以取得人数.前提是取的人的薪水总和不超过总的钱数. 思路:仅仅能在子树中操作.贪心的想,我 ...
- [APIO2012]派遣 可并堆(左偏树)
没啥说的,自底向上合并大根堆即可. 一边合并,一边贪心弹堆顶直到堆的总和不大于预算. Code: #include <cstdio> #include <algorithm> ...
- 「BZOJ 2809」「APIO 2012」Dispatching「启发式合并」
题意 给定一个\(1\)为根的树,每个点有\(c,w\)两个属性,你需要从某个点\(u\)子树里选择\(k\)个点,满足选出来的点\(\sum_{i=1}^k w(i)\leq m\),最大化\(k\ ...
- 浅谈左偏树在OI中的应用
Preface 可并堆,一个听起来很NB的数据结构,实际上比一般的堆就多了一个合并的操作. 考虑一般的堆合并时,当我们合并时只能暴力把一个堆里的元素一个一个插入另一个堆里,这样复杂度将达到\(\log ...
随机推荐
- 学习Linux相关书籍
要推荐的书,我在<那两年炼就的Android内功修养>这篇文章中有提到,这里再列一下出来: 语言类: <深度探索C++对象模型>,对应的英文版是<Inside C+++ ...
- PostgreSQL 监控磁盘使用
监控磁盘使用 1. 判断磁盘用量 每个表都有一个主要的堆磁盘文件,大多数数据都存储在其中.如果一个表有着可能会很宽(尺寸大)的列, 则另外还有一个TOAST文件与这个表相关联, 它用于存储因为太宽而不 ...
- 注解:@interface 自定义注解的语法
自定义注解: 使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节.在定义注解时,不能继承其他的注解或接口 ...
- JavaScript语言基础-对象与数组
- Github中README.md换行
两个以上的空格,然后回车.我date
- Pandoc+markdown生成slides
Pandoc+markdown生成slides 参考:http://blog.csdn.net/pizi0475/article/details/50955900 1.安装 http://pandoc ...
- 运行程序显示:Could not find version 8.3 of the MCR.
- hibernate学习笔记(6)组件属性以及单表操作
组件属性:实体类中的某个属性属于用户自定义类的对象: 作用:将两个实体类合并在一起组建成一个表 在hbm.xml文件中配置: 格式: <component name="取的名字&quo ...
- wpf textblock超出显示范围后显示tooltip
public static class TextTrmmingShowToolTip { public static readonly DependencyProperty IsToolTipProp ...
- 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-006归并排序(Mergesort)
一. 1.特点 (1)merge-sort : to sort an array, divide it into two halves, sort the two halves (recursivel ...