记录编号 170693 评测结果 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
题目名称 [APIO 2012] 派遣 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 1.822 s
提交时间 2015-07-15 07:44:11 内存使用 5.28 MiB
显示代码纯文本
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<vector>
  6. using namespace std;
  7. typedef long long LL;
  8. const int SIZEN=100010;
  9. int N;
  10. class NODE{//大根左偏树的结点
  11. public:
  12. int l,r;
  13. int h;
  14. int val,siz;
  15. LL sum;
  16. #define l(x) tree[x].l
  17. #define r(x) tree[x].r
  18. #define h(x) tree[x].h
  19. #define val(x) tree[x].val
  20. #define siz(x) tree[x].siz
  21. #define sum(x) tree[x].sum
  22. };
  23. NODE tree[SIZEN];
  24. int root[SIZEN]={0};
  25. int merge(int u,int v){
  26. if(!u||!v) return u+v;
  27. if(val(u)<val(v)) swap(u,v);
  28. r(u)=merge(r(u),v);
  29. if(h(l(u))<h(r(u))) swap(l(u),r(u));
  30. h(u)=h(r(u))+1;
  31. siz(u)=siz(l(u))+siz(r(u))+1;
  32. sum(u)=sum(l(u))+sum(r(u))+val(u);
  33. return u;
  34. }
  35. LL MX;//预算
  36. LL leader[SIZEN]={0};
  37. LL ans=0;
  38. int master;
  39. vector<int> c[SIZEN];//存的其实是子节点
  40. void DFS(int x){
  41. root[x]=x;
  42. l(x)=r(x)=0;
  43. h(x)=siz(x)=1;
  44. sum(x)=val(x);
  45. for(int i=0;i<c[x].size();i++){
  46. DFS(c[x][i]);
  47. root[x]=merge(root[x],root[c[x][i]]);
  48. }
  49. while(sum(root[x])>MX) root[x]=merge(l(root[x]),r(root[x]));//合并两个子树就是删去最大点
  50. ans=max(ans,leader[x]*siz(root[x]));
  51. }
  52. void init(void){
  53. scanf("%d",&N);
  54. scanf("%lld",&MX);
  55. int p;
  56. for(int i=1;i<=N;i++){
  57. scanf("%d",&p);
  58. scanf("%lld%lld",&val(i),&leader[i]);
  59. if(!p) master=i;
  60. c[p].push_back(i);
  61. }
  62. }
  63. int main(){
  64. freopen("dispatching.in","r",stdin);
  65. freopen("dispatching.out","w",stdout);
  66. init();
  67. DFS(master);
  68. printf("%lld\n",ans);
  69. return 0;
  70. }