题面

Description

在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿。在这个帮派里,有一名忍者被称之为 Master。除了 Master以外,每名忍者都有且仅有一个上级。为保密,同时增强忍者们的领导力,所有与他们工作相关的指令总是由上级发送给他的直接下属,而不允许通过其他的方式发送。现在你要招募一批忍者,并把它们派遣给顾客。你需要为每个被派遣的忍者 支付一定的薪水,同时使得支付的薪水总额不超过你的预算。另外,为了发送指令,你需要选择一名忍者作为管理者,要求这个管理者可以向所有被派遣的忍者 发送指令,在发送指令时,任何忍者(不管是否被派遣)都可以作为消息的传递 人。管理者自己可以被派遣,也可以不被派遣。当然,如果管理者没有被排遣,就不需要支付管理者的薪水。你的目标是在预算内使顾客的满意度最大。这里定义顾客的满意度为派遣的忍者总数乘以管理者的领导力水平,其中每个忍者的领导力水平也是一定的。写一个程序,给定每一个忍者 i的上级 Bi,薪水Ci,领导力L i,以及支付给忍者们的薪水总预算 M,输出在预算内满足上述要求时顾客满意度的最大值。

1 ≤N ≤ 100,000 忍者的个数;

1 ≤M ≤ 1,000,000,000 薪水总预算;

0 ≤Bi < i 忍者的上级的编号;

1 ≤Ci ≤ M 忍者的薪水;

1 ≤Li ≤ 1,000,000,000 忍者的领导力水平。

Input

从标准输入读入数据。

第一行包含两个整数 N和 M,其中 N表示忍者的个数,M表示薪水的总预算。

接下来 N行描述忍者们的上级、薪水以及领导力。其中的第 i 行包含三个整 Bi , C i , L i分别表示第i个忍者的上级,薪水以及领导力。Master满足B i = 0,并且每一个忍者的老板的编号一定小于自己的编号 Bi < i。

Output

输出一个数,表示在预算内顾客的满意度的最大值。

Sample Input

  1. 5 4
  2. 0 3 3
  3. 1 3 5
  4. 2 2 2
  5. 1 2 4
  6. 2 3 1

Sample Output

  1. 6

HINT

如果我们选择编号为 1的忍者作为管理者并且派遣第三个和第四个忍者,薪水总和为 4,没有超过总预算 4。因为派遣了 2 个忍者并且管理者的领导力为 3,

用户的满意度为 2 ,是可以得到的用户满意度的最大值。

题目大意

题面的表达貌似并不是很清楚.

这题的大意是: 给定一棵有\(n\)个节点的树, 每个节点记录两个值: \(C\)和\(L\). 现在我们要在树上找到一棵以\(u\)为根的子树, 并在这棵子树上取出一些点, 使得\(L[u]\)乘上取的点数得到的值尽可能大, 并且满足\(\sum_{x:取出的点}C[x] \le m\). 求这个最大值是多少.

Solution

大根可并堆, 把选哪些点的问题变成不选哪些点的问题.

  1. #include <cstdio>
  2. #include <cctype>
  3. #include <cstring>
  4. #include <algorithm>
  5. const int N = (int)1e5;
  6. int n, m;
  7. long long ans = 0;
  8. namespace Zeonfai
  9. {
  10. inline int getInt()
  11. {
  12. int a = 0, sgn = 1;
  13. char c;
  14. while(! isdigit(c = getchar()))
  15. if(c == '-')
  16. sgn *= -1;
  17. while(isdigit(c))
  18. a = a * 10 + c - '0', c = getchar();
  19. return a * sgn;
  20. }
  21. }
  22. struct pair
  23. {
  24. long long first, second;
  25. inline pair(int _C = 0, int _L = 0)
  26. {
  27. first = _C, second = _L;
  28. }
  29. inline void friend operator +=(pair& a, pair b)
  30. {
  31. a.first += b.first, a.second += b.second;
  32. }
  33. }A[N + 1];
  34. struct leftistTrees
  35. {
  36. struct node
  37. {
  38. int suc[2], dis;
  39. }nd[N + 1];
  40. int rt[N + 1];
  41. inline void initialize()
  42. {
  43. for(int i = 1; i <= n; ++ i)
  44. nd[i].suc[0] = nd[i].suc[1] = rt[i] = -1, nd[i].dis = 0;
  45. }
  46. int merge(int u, int v)
  47. {
  48. if(! (~ u))
  49. return v;
  50. if(! (~ v))
  51. return u;
  52. if(A[u].first < A[v].first)
  53. std::swap(u, v);
  54. nd[u].suc[1] = merge(nd[u].suc[1], v);
  55. if(! (~ nd[u].suc[0]) || nd[nd[u].suc[0]].dis < nd[nd[u].suc[1]].dis)
  56. std::swap(nd[u].suc[0], nd[u].suc[1]);
  57. nd[u].dis = ~ nd[u].suc[1] ? nd[nd[u].suc[1]].dis + 1 : 0; // 这里不要漏了加1
  58. return u;
  59. }
  60. inline int pop(int u)
  61. {
  62. return merge(nd[u].suc[0], nd[u].suc[1]);
  63. }
  64. }hp;
  65. struct tree
  66. {
  67. int hd[N + 1], tp;
  68. inline void initialize()
  69. {
  70. memset(hd, -1, sizeof(hd));
  71. tp = 0;
  72. }
  73. struct edge
  74. {
  75. int v, nxt;
  76. }edg[N];
  77. inline void addEdge(int u, int v)
  78. {
  79. edg[tp].v = v, edg[tp].nxt = hd[u];
  80. hd[u] = tp ++;
  81. }
  82. pair DFS(int u)
  83. {
  84. pair res;
  85. for(int p = hd[u]; ~ p; p = edg[p].nxt)
  86. {
  87. res += DFS(edg[p].v);
  88. hp.rt[u] = hp.merge(hp.rt[u], hp.rt[edg[p].v]);
  89. }
  90. hp.rt[u] = hp.merge(hp.rt[u], u), res.first += A[u].first, ++ res.second;
  91. while(res.first > m)
  92. res.first -= A[hp.rt[u]].first, -- res.second, hp.rt[u] = hp.pop(hp.rt[u]);
  93. ans = std::max(ans, A[u].second * res.second);
  94. return res;
  95. }
  96. inline void getAnswer()
  97. {
  98. ans = 0;
  99. DFS(1);
  100. }
  101. }org;
  102. int main()
  103. {
  104. #ifndef ONLINE_JUDGE
  105. freopen("XSY1036.in", "r", stdin);
  106. freopen("XSY1036.out", "w", stdout);
  107. #endif
  108. using namespace Zeonfai;
  109. n = getInt(), m = getInt();
  110. org.initialize();
  111. for(int i = 1; i <= n; ++ i)
  112. {
  113. int pre = getInt();
  114. A[i].first = getInt(), A[i].second = getInt();
  115. if(pre)
  116. org.addEdge(pre, i);
  117. }
  118. hp.initialize();
  119. org.getAnswer();
  120. printf("%lld\n", ans);
  121. }

XSY1036 [Apio2012]派遣的更多相关文章

  1. 数据结构,可并堆(左偏树):COGS [APIO2012] 派遣

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

  2. [APIO2012]派遣

    [APIO2012]派遣 题目大意: 给定一棵\(n(n\le10^5)\)个结点的有根树,每个点有代价\(c_i\)和权值\(l_i\),要求你选定一个结点\(k\),并在对应的子树中选取一个点集\ ...

  3. [luogu P1552] [APIO2012]派遣

    [luogu P1552] [APIO2012]派遣 题目背景 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿. 题目描述 在这个帮派里,有一名忍者被称之为Master.除 ...

  4. 洛谷1552 [APIO2012]派遣

    洛谷1552 [APIO2012]派遣 原题链接 题解 luogu上被刷到了省选/NOI- ...不至于吧 这题似乎有很多办法乱搞? 对于一个点,如果他当管理者,那选的肯定是他子树中薪水最少的k个,而 ...

  5. [APIO2012]派遣 左偏树

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

  6. BZOJ2809&&LG1552 APIO2012派遣(线段树合并)

    BZOJ2809&&LG1552 APIO2012派遣(线段树合并) 题面 自己找去 HINT 简化一题面就是让你从每个点的子树中以\(<=m\)的代价选取尽可能多的点,然后乘上 ...

  7. APIO2012派遣

    2809: [Apio2012]dispatching Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1196  Solved: 586[Submit ...

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

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

  9. APIO2012 派遣dispatching | 左偏树

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

随机推荐

  1. hihocoder1175 拓扑排序2

    #1175 : 拓扑排序·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho所在学校的校园网被黑客入侵并投放了病毒.这事在校内BBS上立刻引起了大家的讨论 ...

  2. Python属性描述符(一)

    描述符是对多个属性运用相同存取逻辑的一种方式,,是实现了特性协议的类,这个协议包括了__get__.__set__和__delete__方法.property类实现了完整的描述符协议.通常,可以只实现 ...

  3. luogu3690 【模板】Link Cut Tree (动态树)

    参考there和there 题单 #include <iostream> #include <cstdio> using namespace std; int n, m, va ...

  4. BugBash活动分享

    此文已由作者夏君授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. BugBash源至微软概念,翻译为<缺陷大扫除>,顾名思义是集中大家力量全面清扫Bug,确保产品质 ...

  5. Leetcode30--->Substring with Concatenation of All Words(主串中找出连接给定所有单词的子串的位置)

    题目:给定一个字符串S(主串),一个字符串数组words,其中的字符串的长度相同.找到所有的子串位置,要求是words中字符串的一个连接: 举例: For example, given:s: &quo ...

  6. 【转】hibernate延迟加载和抓取策略

    一.延迟加载 1.简单查询get,load 针对对象本身延迟或即时 当使用load方法来得到一个对象时,此时hibernate会使用延迟加载的机制来加载这个对象,即:当我们使用session.load ...

  7. iOS学习笔记46-Swift(六)扩展

    一.Swift扩展 扩展就是向一个已有的类.结构体或枚举类型添加新功能,这包括在没有权限获取原始源代码的情况下扩展类型的能力.扩展和 Objective-C中的分类(category)类似,但是它要比 ...

  8. 【bzoj4800】[Ceoi2015]Ice Hockey World Championship 折半搜索

    题目描述 有n个物品,m块钱,给定每个物品的价格,求买物品的方案数. 输入 第一行两个数n,m代表物品数量及钱数 第二行n个数,代表每个物品的价格 n<=40,m<=10^18 输出 一行 ...

  9. 解决ul的li横向排列换行的问题

    1. 问题现象 先看下面的html结构: <div> <ul> <li><img src='./img/1.jpg'></li> <l ...

  10. AIX 常用命令 第一步(uname,lspv)

    如何知道自己在运行单处理器还是多处理器内核? /unix 是指向已启动内核的符号链接.要了解正在运行什么内核模式,可输入 ls -l /unix 并查看 /unix 链接到什么文件.下面是 ls -l ...