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 ...
随机推荐
- Day2-Python基础2---字符串操作
一.字符串操作 特性:不可修改 name = "my \tname is {name} and i am {year} old" #首字母大写.capitalize print(n ...
- java继承实例基础
总结:多态.重写.构造方法调用 package com.a; public class fsd { int a = 23; public fsd() { System.out.println(4444 ...
- 2016.3.7 Word2007编号设置
1.点击下图红圈出的下拉箭头 2.点击下图新建样式按钮 3.在弹出窗口中,设置名称AAA(方便稍后的查找修改),样式类型改为列表,点击编号 4.在弹出的窗口中以此设置各级标题的编号样式,保存后设置成功 ...
- C#调用带返回值的存储过程
()在SQL Server中建立如下的存储过程: set ANSI_NULLS ON set QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[GetNa ...
- MySQL学习笔记之一---字符编码和字符集
前言: 一般来说,出现中文乱码,都是客户端和服务端字符集不匹配导致的原因. (默认未指定字符集创建的数据库表,都是latinl字符集, 强烈建议使用utf8字符集) 保证不出现乱码的思想:保证客户 ...
- java之类和对象
类的成员: 成员变量和成员函数. 成员函数:构造函数和普通函数. 构造函数: 作用:自动对对象进行初始化 特点:1.方法名和类名一致 2.没有返回值 问: 1.我们能够定义几次构造函数? 我们可以定义 ...
- hibernate学习笔记(4)表单操作
User.hbm.xml的表单配置: ①主键 <id name="id" type="java.lang.Integer"> <column ...
- c语言中argc和argv
main函数的参数,解释如下: argc:命令行总的参数的个数,即argv中元素的格式. *argv[ ]:字符串数组,用来存放指向你的字符串参数的指针数组,每一个元素指向一个参数. argv[0]: ...
- day70-oracle PLSQL_02光标
涨工资之前员工的工资. 如果PLSQL程序没有commit的话,命令行这边的客户端是无法读到的.这是oracle数据库的隔离级别. 为什么在PLSQL程序中commit之后还是不行呢? PLSQL程序 ...
- [hadoop入门]mapper与reducer(word_count计数demo)
1.mapper #!/usr/bin/env python import sys for line in sys.stdin: line = line.strip() words = line.sp ...