[BZOJ2809][Apio2012]dispatching 贪心+可并堆
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2809
我们考虑以每一个节点作为管理者所得的最优答案,一定是优先选择所要薪水少的忍者。那么首先整棵子树的忍者都选上,如果总和大于$M$,那么就不断删除薪水最大的那一个忍者。
然后考虑从下至上合并节点,我们需要一个支持合并的数据结构,就想到了启发式合并平衡树或者可并堆。
可并堆基本原理是维护一个$dis$,表示从根节点到达叶子节点的最短距离,要求$dis[lch]>=dis[rch]$。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int inline readint(){
int Num;char ch;
while((ch=getchar())<''||ch>'');Num=ch-'';
while((ch=getchar())>=''&&ch<='') Num=Num*+ch-'';
return Num;
}
int N,M;
int C[],L[];
int to[],ne[],fir[],cnt=;
void Add(int a,int b){
to[++cnt]=b;
ne[cnt]=fir[a];
fir[a]=cnt;
}
int lch[],rch[];
ll sum[];
int siz[],dis[];
ll ans=;
int merge(int x,int y){
if(!x||!y) return x?x:y;
if(C[x]<C[y]) swap(x,y);
rch[x]=merge(rch[x],y);
if(dis[lch[x]]<dis[rch[x]]) swap(lch[x],rch[x]);
dis[x]=dis[rch[x]]+;
sum[x]=sum[lch[x]]+sum[rch[x]]+C[x];
siz[x]=siz[lch[x]]+siz[rch[x]]+;
return x;
}
int Build(int x){
int rt=x;
sum[rt]=C[x];
siz[rt]=;
for(int i=fir[x];i!=-;i=ne[i])
rt=merge(rt,Build(to[i]));
while(sum[rt]>M)
rt=merge(lch[rt],rch[rt]);
ans=max(ans,(ll)siz[rt]*L[x]);
return rt;
}
int main(){
memset(fir,-,sizeof(fir));
N=readint();
M=readint();
for(int i=;i<=N;i++){
int fa=readint();
C[i]=readint();
L[i]=readint();
Add(fa,i);
}
Build();
printf("%lld\n",ans);
return ;
}
[BZOJ2809][Apio2012]dispatching 贪心+可并堆的更多相关文章
- 【bzoj2809】[Apio2012]dispatching 贪心+可并堆
题目描述 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个上级.为保密,同时增 ...
- bzoj2809 [Apio2012]dispatching(左偏树)
[Apio2012]dispatching Description 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 M ...
- BZOJ2809 [Apio2012]dispatching 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2809 题意概括 n个点组成一棵树,每个点都有一个领导力和费用,可以让一个点当领导,然后在这个点的子 ...
- bzoj2809 [Apio2012]dispatching——左偏树(可并堆)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2809 思路有点暴力和贪心,就是 dfs 枚举每个点作为管理者: 当然它的子树中派遣出去的忍者 ...
- BZOJ2809: [Apio2012]dispatching
传送门 主席树经典题. 首先把树搞出来,然后搞出来DFS序.然后离散化点权,在DFS序上建立主席树. 对于每个点对应的区间,查找对应的区间最大的点数即可. //BZOJ2809 //by Cydiat ...
- BZOJ2809——[Apio2012]dispatching
1.题目大意:给一棵树和M值,每个点有两个权值C和L,选x个点,这x个点的C值的和不能超过M,且这x个点如果都在某个子树内 定义满意度为x*这个子树的根的L值 2.分析:这是一道可并堆的题目,我们考虑 ...
- bzoj2806 [Apio2012]dispatching【可并堆】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2809 保存可并堆模版代码. #include <cstdio> #include ...
- BZOJ 2809: [Apio2012]dispatching(可并堆 左偏树板题)
这道题只要读懂题目一切好说. 给出nnn个点的一棵树,每一个点有一个费用vvv和一个领导力aaa,给出费用上限mmm.求下面这个式子的最大值ax∗∣S∣ ( S⊂x的子树, ∑iv[i]≤m )\la ...
- [BZOJ2809][Apio2012]dispatching(左偏树)
首先对于一个节点以及它的子树,它的最优方案显然是子树下选最小的几个 用左偏树维护出每棵子树最优方案的节点,记录答案 然后它的这棵树可以向上转移给父节点,将所有子节点的左偏树合并再维护就是父节点的最优方 ...
随机推荐
- 【剑指offer】数组中仅仅出现一次的数字(1)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/27649027 题目描写叙述: 一个整型数组里除了两个数字之外.其它的数字都出现了两次. 请 ...
- Android之弹出多级菜单
使用布局文件创建菜单:(多级菜单) 在res下创建目录menu(假设已经有啦就不用再创建了) 在该menu目录下创建XML文件这里我把文件名称命名为menu 在创建的menu.XML文件里 写入: & ...
- android通过adb wireless的使用
转自:http://www.cnblogs.com/Androider123/p/3848415.html?utm_source=tuicool 开发android程序,总是需要插拔插拔的,usb口都 ...
- 【bzoj1561】[JSOI2009]去括号
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> # ...
- JDBC连接数据库查询信息的步骤(提取成配置文件方式)
硬编码格式的弊端:数据库发生改变时,要重新修改代码,重新编译和部署 解决方法:将数据库信息写在配置文件当中,让程序通过读取配置文件来获得这些信息 jdbc.driver.class=com.mysql ...
- “Invalid configuration file. File "I:/My Virtual Machines/Windows XP english Professional/Windows XP Professional.vmx" was created by a VMware product
“Invalid configuration file. File "I:/My Virtual Machines/Windows XP english Professional/Windo ...
- 关于warning: Clock skew detected. Your build may be incomplete. 的解决方法【转】
本文转载自:http://blog.csdn.net/jeesenzhang/article/details/40300127 今天发现电脑的系统时间不正确,因此将时钟进行了修改,回头编译Linux ...
- Splay 区间反转
同样的,我们以一道题来引入. 传送门 这次的任务比较少,只要求进行区间反转.区间反转? 这个好像用啥都是O(n)的吧……(这次vector,set也救不了你了) 我们来使用splay解决这个问题.我们 ...
- [USACO16JAN]愤怒的奶牛Angry Cows
传送门 一道神奇的DP………(鬼知道他为什么在tarjan里面) 一开始可能会考虑贪心或者什么其他神奇的算法,不过还是DP比较靠谱. 我们用f[i]表示摧毁所有i左侧的炸 药包最少需要的能量,用g[i ...
- HDU 3944 DP? (Lucas定理)
题意:在杨辉三角中让你从最上面到 第 n 行,第 m 列所经过的元素之和最小,只能斜向下或者直向下走. 析:很容易知道,如果 m 在n的左半部分,那么就先从 (n, m)向左,再直着向上,如果是在右半 ...