题目描述







题解

一种显然的水法:max(0,-(点权-边权之和*2))

这样会挂是因为在中途体力值可能会更小,所以考虑求走完每棵子树所需的至少体力值


考虑从子树往上推求出当前点的答案

设每棵子树从根往下走的所需体力值为f,走完的贡献为sum

由于要加上 当前点-->儿子 这条边,所以实际上走完的贡献sum'=sum-边权*2

所需的体力值f'=max(边权+f,2*边权-sum),这里其实有两种情况

①当前点-->儿子-->子树(-->儿子),那么最坏情况就是(子树的最坏情况+边权)

②当前点-->儿子-->子树-->儿子-->当前点,最终的贡献实际为sum-边权*2,那么就需要至少max(0,边权*2-sum)的体力


显然对于贡献≥0的点按照需求从小到大取

对于贡献<0的点,定义减少量=-贡献

那么按照需求-减少量从大到小排序即可

证明:

定义差值=需求-减少量

对于两个儿子,设第一个儿子的差值和减少量分别为a和b,第二个为cd

先假设已经按照差值排序,且排序后两个儿子相邻,那么有a≥c

证明交换后不会更优

设x为走这两棵子树前的体力,保证在中途不会出现负数且能达到需求量

那么有

交换前:

x≥a+b,x-b≥c+d

交换后:

x≥c+d,x-d≥a+b

根据式子

根节点贡献+恢复的体力-每棵子树的减少量之和=剩余体力,其中只有恢复的体力是变量,所以可以发现剩余体力越少=答案越小

由于交换前后剩余的体力都是x-b-d,所以要使x尽量小(太大可能会导致有剩余)

所以变成证明

max(a+b,b+c+d)≤max(c+d,a+b+d)

由于a+b+d≤max(c+d,a+b+d),且a+b+d≥a+b和b+c+d(a≥c),所以max(a+b,b+c+d)≤a+b+d≤max(c+d,a+b+d)

得证

code

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <cstdio>
  6. #define fo(a,b,c) for (a=b; a<=c; a++)
  7. #define fd(a,b,c) for (a=b; a>=c; a--)
  8. #define min(a,b) (a<b?a:b)
  9. #define max(a,b) (a>b?a:b)
  10. using namespace std;
  11. struct type{
  12. long long f,sum;
  13. } b[100001],c[100001];
  14. int a[200001][3];
  15. int ls[100001];
  16. int w[100001];
  17. long long f[100001];
  18. long long sum[100001];
  19. int n,i,j,k,l,len;
  20. long long ans;
  21. bool cmp(type a,type b)
  22. {
  23. return a.f<b.f;
  24. }
  25. bool Cmp(type a,type b)
  26. {
  27. return a.f-a.sum>b.f-b.sum;
  28. }
  29. void New(int x,int y,int z)
  30. {
  31. ++len;
  32. a[len][0]=y;
  33. a[len][1]=ls[x];
  34. a[len][2]=z;
  35. ls[x]=len;
  36. }
  37. void dfs(int Fa,int t)
  38. {
  39. int i,l1=0,l2=0;
  40. long long now=w[t];
  41. sum[t]=w[t];
  42. for (i=ls[t]; i; i=a[i][1])
  43. if (a[i][0]!=Fa)
  44. {
  45. dfs(t,a[i][0]);
  46. sum[t]+=sum[a[i][0]]-a[i][2]-a[i][2];
  47. }
  48. if (!ls[t]) return;
  49. for (i=ls[t]; i; i=a[i][1])
  50. if (a[i][0]!=Fa)
  51. {
  52. if (sum[a[i][0]]-a[i][2]-a[i][2]>=0)
  53. {
  54. ++l1;
  55. b[l1].f=max(f[a[i][0]]+a[i][2],-(sum[a[i][0]]-a[i][2]-a[i][2]));
  56. b[l1].sum=sum[a[i][0]]-a[i][2]-a[i][2];
  57. }
  58. else
  59. {
  60. ++l2;
  61. c[l2].f=max(f[a[i][0]]+a[i][2],-(sum[a[i][0]]-a[i][2]-a[i][2]));
  62. c[l2].sum=-(sum[a[i][0]]-a[i][2]-a[i][2]);
  63. }
  64. }
  65. if (l1)
  66. {
  67. sort(b+1,b+l1+1,cmp);
  68. fo(i,1,l1)
  69. {
  70. if (now<b[i].f)
  71. {
  72. f[t]+=b[i].f-now;
  73. now=b[i].f;
  74. }
  75. now+=b[i].sum;
  76. }
  77. }
  78. if (l2)
  79. {
  80. sort(c+1,c+l2+1,Cmp);
  81. if (now<(c[1].f-c[1].sum))
  82. {
  83. f[t]+=(c[1].f-c[1].sum)-now;
  84. now=0;
  85. }
  86. else
  87. now-=(c[1].f-c[1].sum);
  88. fo(i,1,l2)
  89. {
  90. if (i>1)
  91. now+=(c[i-1].f-c[i-1].sum)-(c[i].f-c[i].sum);
  92. if (now<c[i].sum)
  93. {
  94. f[t]+=c[i].sum-now;
  95. now=c[i].sum;
  96. }
  97. now-=c[i].sum;
  98. }
  99. }
  100. }
  101. int main()
  102. {
  103. // freopen("a.in","r",stdin);
  104. // freopen("b.out","w",stdout);
  105. freopen("horse.in","r",stdin);
  106. freopen("horse.out","w",stdout);
  107. scanf("%d",&n);
  108. fo(i,1,n)
  109. scanf("%d",&w[i]);
  110. fo(i,2,n)
  111. {
  112. scanf("%d%d%d",&j,&k,&l);
  113. New(j,k,l);
  114. New(k,j,l);
  115. }
  116. dfs(0,1);
  117. printf("%lld\n",f[1]);
  118. fclose(stdin);
  119. fclose(stdout);
  120. return 0;
  121. }

6364. 【NOIP2019模拟2019.9.20】养马的更多相关文章

  1. NOIP2019模拟2019.9.20】膜拜大会(外向树容斥,分类讨论)

    传送门. 题解: 我果然是不擅长分类讨论,心态被搞崩了. 注意到\(m<=n-2\),意味着除了1以外的位置不可能被加到a[1]两遍. 先考虑个大概: 考虑若存在\(x,x-1,-,2\)(有序 ...

  2. 6359. 【NOIP2019模拟2019.9.15】小ω的树(tree)(定期重构)

    题目描述 题解 qy的毒瘤题 CSP搞这种码农题当场手撕出题人 先按照边权从大到小建重构树,然后40%暴力修改+查找即可 100%可以定期重构+平衡规划,每次把B个询问拉出来建虚树,在虚树上暴力维护每 ...

  3. [JZOJ6075]【GDOI2019模拟2019.3.20】桥【DP】【线段树】

    Description N,M<=100000,S,T<=1e9 Solution 首先可以感受一下,我们把街道看成一行,那么只有给出的2n个点的纵坐标是有用的,于是我们可以将坐标离散化至 ...

  4. 6424. 【NOIP2019模拟2019.11.13】我的订书机之恋

    题目描述 Description Input Output Sample Input 见下载 Sample Output 见下载 Data Constraint 题解 lj题卡线段树 求出每个右端点往 ...

  5. 6392. 【NOIP2019模拟2019.10.26】僵尸

    题目描述 题解 吼题但题解怎么这么迷 考虑一种和题解不同的做法(理解) 先把僵尸离散化,h相同的钦(ying)点一个大小 (可以发现这样每种情况只会被算正好一次) 计算完全被占领的方案,然后1-方案/ ...

  6. 6389. 【NOIP2019模拟2019.10.26】小w学图论

    题目描述 题解 之前做过一次 假设图建好了,设g[i]表示i->j(i<j)的个数 那么ans=∏(n-g[i]),因为连出去的必定会构成一个完全图,颜色互不相同 从n~1染色,点i的方案 ...

  7. 6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]

    题目描述 题解 随便bb 详细题解见 https://www.cnblogs.com/coldchair/p/11624979.html https://blog.csdn.net/alan_cty/ ...

  8. 6362. 【NOIP2019模拟2019.9.18】数星星

    题目描述 题解 一种好想/好写/跑得比**记者还快的做法: 对所有询问排序,按照R递增的顺序来处理 维护每个点最后一次被覆盖的时间,显然当前右端点为R时的答案为所有时间≥L的点的权值之和 LCT随便覆 ...

  9. 【NOIP2019模拟2019.11.13】旅行 && GDKOI2018 还念(二分答案+dij)

    Description: 题解: 显然满足二分性. 并且每一条边要不选l要不选r. 二分的那条链肯定要选l. 考虑有两个人在走最短路,一个人一开始必须走二分的那条链,要求第一个人走的比第二个人快. 安 ...

随机推荐

  1. HTML学习之==>HTML标签

    前端的三把利器: HTML:一个人 CSS:这个人的衣服 JS:这个人的行为 HTML(超文本标记语言) html代码实际上就是一套能够被浏览器所识别的规则代码,由一个个标签组成.html代码就是一大 ...

  2. CMakeLists.txt中使用循环

    编译一个安卓下的so,此so依赖其他的库,通过循环简化操作 set(UVC_LIBS UVCCamera uvc usb100 jpeg-turbo1500) FOREACH(UVC_LIB ${UV ...

  3. Lesson 4 The double life of Alfred Bloggs

    There are two type of people in the society. People who do manual works can higher payment than peop ...

  4. vue--》如何使用wacth监听对象的属性变化?

    在开发过程中,我们经常需要监听watch监听一个对象的变化,但是如何来实现     监听对象中属性的变化呢? 先回顾一下如何监听整个对象的变化,使用watch就行了 export default { ...

  5. C++中的数组操作符重载

    1,本文讲述数组操作符重载,上篇博文的字符串类 string 确实强大,但 string 类  对象还具备 C 方式字符串的灵活性吗?还能直接访问单个字符吗? 1,C 方式字符串灵活性是指能够通过数组 ...

  6. P1474货币系统

    这是USACO的一道DP题,难度是提高—. 这道题是告诉我们货币种类,问你用这些货币组成一个面值最大有多少种方案.第一眼看上去想用dfs记忆化,随后发现其实这个题很类似于完全背包,可以取无线件,但是他 ...

  7. PDFObject的使用(转)

    1.pdfobject.js官网:https://pdfobject.com/ 2.在html文件中引入这个文件,以pdfobject.min.js为例 1 <script type=" ...

  8. 洛谷 - P1522 - 牛的旅行 - Cow Tours - Floyd

    https://www.luogu.org/problem/P1522 好坑啊,居然还有直径不通过新边的数据,还好不是很多. 注意一定要等Floyd跑完之后再去找连通块的直径,不然一定是INF. #i ...

  9. SpringMVC源码解析

    一:springmvc运行过程: 1. dispatcherServlet 通过 HandlerMapping 找到controller2. controller经过后台逻辑处理得到结果集modela ...

  10. python 框架

    支持异步的 python web 框架 tornado 轻量级 flask 框架 flask中文文档 import base64 import random import io import time ...