Problem
【APIO2012】Dispatching
Description
在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿。
在这个帮派里,有一名忍者被称之为。除了以外,每名忍者都有且仅有一个上级。为保密,同时增强忍者们的领导力,所有与他们工作相关的指令总是由上级发送给他的直接下属,而不允许通过其他的方式发送。
现在你要招募一批忍者,并把它们派遣给顾客。你需要为每个被派遣的忍者支付一定的薪水,同时使得支付的薪水总额不超过你的预算。另外,为了发送指令,你需要选择一名忍者作为管理者,要求这个管理者可以向所有被派遣的忍者发送指令,在发送指令时,任何忍者(不管是否被派遣)都可以作为消息的传递人。管理者自己可以被派遣,也可以不被派遣。当然,如果管理者没有被排遣,就不需要支付管理者的薪水。你的目标是在预算内使顾客的满意度最大。
这里定义顾客的满意度为派遣的忍者总数乘以管理者的领导力水平,其中每个忍者的领导力水平也是一定的。
写一个程序,给定每一个忍者的上级,薪水,领导力,以及支付给忍者们的薪水总预算,输出在预算内满足上述要求时顾客满意度的最大值。
Input
从标准输入读入数据。
第一行包含两个整数和,其中表示忍者的个数,表示薪水的总预算。
接下来行描述忍者们的上级、薪水以及领导力。其中的第行包含三个整数分别表示第个忍者的上级,薪水以及领导力。满足,并且每一个忍者的老板的编号一定小于自己的编号。
Output
Sample Input
1 | 5 4 |
Sample Output
1 | 6 |
Hint
样例解释
如果我们选择编号为的忍者作为管理者并且派遣第三个和第四个忍者,薪水总和为,没有超过总预算。
因为派遣了个忍者并且管理者的领导力为,用户的满意度为,是可以得到的用户满意度的最大值。
数据范围
标签:可并堆
左偏树
Solution
可并堆基础题。
对于每个结点作领导的情况,贪心策略肯定在其子树中从小往大选,直到选不了为止。可以每个结点用一个堆维护,但遍历子树会导致复杂度爆炸。
考虑每次用已经算出的一些结点的答案。那么可以想到一种做法:
将每个结点子树中的所有点默认先选上,再从大往小去掉直到可行为止。这样在儿子结点中都没选到的点一定不会在父节点中选到。于是可以直接将每个结点最后选出的点加入到父亲的备选点集中。这样不难发现可以用可并堆维护,时将所有儿子结点的可并堆并起来,再从大往小点,找到可行最大后更新答案即可。
Code
1 |
|