传送门

Description

一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的。

有K个人(分布在K个不同的点)要集中到一个点举行聚会。

聚会结束后需要一辆车从举行聚会的这点出发,把这K个人分别送回去。

请你回答,对于i=1~n,如果在第i个点举行聚会,司机最少需要多少时间把K个人都送回家。

Input

第一行两个数,n,K。

接下来n-1行,每行三个数,x,y,z表示x到y之间有一条需要花费z时间的边。

接下来K行,每行一个数,表示K个人的分布。

Output

输出n个数,第i行的数表示:如果在第i个点举行聚会,司机需要的最少时间。

Sample Input

7 2

1 2 4

1 3 1

2 5 1

2 4 2

4 7 3

4 6 2

3

7

Sample Output

11

15

10

13

16

15

10

HINT

【数据规模】

K <= N <= 500000

1 <= x,y <= N, 1 <= z <= 1000000

Solution

总体上是用全部的路程减去最大的一条路程

先两次dfs求出每个点全部路程

再两次dfs求出最大一条路径

Code

  1. //By Menteur_Hxy
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<iostream>
  6. #include<algorithm>
  7. #define M(a,b) memset(a,(b),sizeof(a))
  8. #define F(i,a,b) for(register int i=(a);i<=(b);i++)
  9. #define E(i,u) for(register int i=head[u];i;i=nxt[i])
  10. using namespace std;
  11. typedef long long LL;
  12. int read() {
  13. int x=0,f=1; char c=getchar();
  14. while(!isdigit(c)) {if(c=='-')f=-f; c=getchar();}
  15. while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
  16. return x*f;
  17. }
  18. const int N=500010;
  19. const LL INF=0x7fffffffffffffff;
  20. int n,k,cnt;
  21. int nxt[N<<1],to[N<<1],w[N<<1],head[N],siz[N];
  22. LL dis[N],down[N][2],up[N];
  23. void dfs1(int u,int pre) { //向下
  24. E(i,u) { int v=to[i];
  25. if(v==pre) continue;
  26. dfs1(v,u); siz[u]+=siz[v];
  27. dis[u]+=dis[v]+(siz[v]?w[i]:0);
  28. }
  29. }
  30. void dfs2(int u,int pre) { //向上
  31. E(i,u) { int v=to[i];
  32. if(v==pre) continue;
  33. dis[v]=dis[u];
  34. // if(siz[v])dis[v]-=w[i];
  35. // if(siz[v]<k)dis[v]+=w[i];
  36. if(siz[v]==k) dis[v]-=w[i];
  37. else if(!siz[v]) dis[v]+=w[i];
  38. dfs2(v,u);
  39. }
  40. }
  41. void dfs3(int u,int pre) { //向下
  42. down[u][0]=down[u][1]=(siz[u]?0:-INF);
  43. E(i,u) { int v=to[i];
  44. if(v==pre) continue;
  45. dfs3(v,u);
  46. if(down[v][0]+w[i]>down[u][0]) down[u][1]=down[u][0],down[u][0]=down[v][0]+w[i];
  47. else if(down[v][0]+w[i]>down[u][1]) down[u][1]=down[v][0]+w[i];
  48. }
  49. }
  50. void dfs4(int u,int pre) { //向上
  51. E(i,u) { int v=to[i];
  52. if(v==pre) continue;
  53. if(down[v][0]+w[i]==down[u][0]) up[v]=down[u][1]+w[i];
  54. else up[v]=down[u][0]+w[i];
  55. up[v]=max(up[v],up[u]+w[i]);
  56. dfs4(v,u);
  57. }
  58. }
  59. #define add(a,b,c) nxt[++cnt]=head[a],to[cnt]=b,w[cnt]=c,head[a]=cnt
  60. int main() {
  61. n=read(),k=read();
  62. F(i,1,n-1) {
  63. int a=read(),b=read(),c=read();
  64. add(a,b,c),add(b,a,c);
  65. }
  66. F(i,1,k) siz[read()]=1;
  67. dfs1(1,0); dfs2(1,0); dfs3(1,0);
  68. up[1]=(siz[1]?0:-INF); dfs4(1,0);
  69. // F(i,1,n) printf("%lld ",2*dis[i]);cout<<endl;
  70. F(i,1,n) printf("%lld\n",2*dis[i]-max(up[i],down[i][0]));
  71. return 0;
  72. }

[bzoj3743 Coci2015] Kamp(树形dp)的更多相关文章

  1. 【BZOJ3743】[Coci2015]Kamp 树形DP

    [BZOJ3743][Coci2015]Kamp Description 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的点)要集中到一个点举 ...

  2. bzoj 3743 [Coci2015]Kamp——树形dp+换根

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3743 树形dp+换根. “从根出发又回到根” 减去 “mx ” . 注意dfsx里真的要改那 ...

  3. bzoj3743 [Coci2015]Kamp 常州模拟赛d6t2

    3743: [Coci2015]Kamp Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 484  Solved: 229[Submit][Status ...

  4. 『kamp 树形dp』

    kamp Description jz 市的云台山是个很美丽的景区,小 x 暑期到云台山打工,他的任务是开景区的大巴. 云台山景区有 N 个景点,这 N 个景点由 N-1 条道路连接而成,我们保证这 ...

  5. bzoj 3743 [ Coci 2015 ] Kamp —— 树形DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3743 一开始想到了树形DP,处理一下子树中的最小值,向上的最小值,以及子树中的最长路和向上的 ...

  6. 2018.09.28 bzoj3743: [Coci2015]Kamp(树形dp)

    传送门 这是一道很有意思的题. 我们把所有的关键点都提出来,当成一棵有边权的虚树. 然后发现虚树上除最后不回到虚根的那条路径外外每条边都会被走两遍. 显然要让答案最优,不走的路径应该在虚树的直径上,于 ...

  7. [Bzoj3743][Coci2015] Kamp【换根Dp】

    Online Judge:Bzoj3743 Label:换根Dp,维护最长/次长链 题目描述 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的 ...

  8. BZOJ3743 COCI2015Kamp(树形dp)

    设f[i]为由i开始遍历完子树内所要求的点的最短时间,g[i]为由i开始遍历完子树内所要求的点最后回到i的最短时间.则g[i]=Σ(g[j]+2),f[i]=min{g[i]-g[j]+f[j]-1} ...

  9. bzoj3743: [Coci2015]Kamp

    首先树dp求出一个点的答案 然后再一遍dfs换根(是叫做换根吗.. 详见代码 #include <iostream> #include <cstdio> #include &l ...

随机推荐

  1. ExtJs之Ext.Model的MemoryProxy

    书上的代码已完全不可参考,只好按知识点从网上查资料一个一个实例 了. <!DOCTYPE html> <html> <head> <title>ExtJ ...

  2. Lua5.2 请求 luasocket 相关模块时的 multiple-lua-vms-detected

    首先说一下5.3貌似没有这个问题, 可是眼下最新版的luasocket 3.0 rc1仅仅能支持5.2, 5.3调用的话程序会崩溃(不知道是不是我没配置好) 出现这个问题的解决办法, 想必网上有非常多 ...

  3. openstack中Nova组件Networks的全部python API 汇总

    感谢朋友支持本博客.欢迎共同探讨交流.因为能力和时间有限.错误之处在所难免,欢迎指正! 假设转载,请保留作者信息. 博客地址:http://blog.csdn.net/qq_21398167 原博文地 ...

  4. HDU 1576 A/B(扩展欧几里德变形)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 Problem Description 要求(A/B)%9973,但因为A非常大,我们仅仅给出n ...

  5. Linux实时查看日志,访问前10IP 和相关命令

    Nginx日志分析可以获得很多有用的信息,现在来试试最基本的,获取最多访问的前10个IP地址及访问次数. 既然是统计,那么awk是必不可少的,好用而高效. 命令如下: awk '{a[$1] += 1 ...

  6. ORA-27301: OS failure message: Not enough space

    OS:HP-UNIX ORA-27300: OS system dependent operation:fork failed with status: 12  ORA-27301: OS failu ...

  7. Warning: File `src/core/nginx.h&#39; has modification time 1.2e+07 s in the future

    Nginx安装时Warning: File `src/core/nginx.h' has modification time 1.2e+07 s in the future问题的解决方法 问题场景: ...

  8. luogu3799 妖梦拼木棒

    题目大意 有n根木棒,现在从中选4根,想要组成一个正三角形,问有几种选法?木棒长度都<=5000. 题解 根据容斥原理,三角形两条边分别由长度相等的单根木棒组成,另一条边由两条小于该边长的木棒构 ...

  9. luogu2833 等式

    题目大意 给出\(a,b,c,x_1,x_2,y_1,y_2\),求满足\(ax+by+c=0\),且\(x\in[x1,x2],y\in [y1,y2]\)的整数解有多少对. 题解 用扩展欧几里得算 ...

  10. Linux之convert命令【转】

    本文转载自:http://zlb1986.iteye.com/blog/778054 转载: 强大的convert命令 convert命令可以用来转换图像的格式,支持JPG, BMP, PCX, GI ...