3743: [Coci2015]Kamp

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 484  Solved: 229
[Submit][Status][Discuss]

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
分析:本来想用状压dp的,但是n这么大,怎么压的下来。其实这道题有一个结论:如果我们把要送达的点建立一棵树,那么答案就是这棵树上的边权和*2+i到这棵树的最短距离(假设为j点)-j到树上最远一点的距离.其实也很好想为什么,要遍历树上的点最少肯定要每条边都走两次,i点要到这棵树上肯定要走最短距离,我们到一个点后就不回起点了,那么肯定终点在最远的那个点上.
      那么想要做出这道题就要用到4个dfs.首先求出每个点在不在树上,然后求出i到树上最近的点和最短距离,接下来求出每个点到它的叶子节点的最长距离和次长距离,最后求出每个点的最长距离.
      第一步和第二步很好理解,关键是最后两步,我们求最长距离为什么还要求每个点到它的叶子节点的最长距离和次长距离呢?其实这有点像树链剖分,我们把树链分为最长链和次长链,位于最长链的儿子成为重儿子,重儿子的最远距离点肯定在它的子节点中或者次长链中,这就包含了最长链和次长链两种情况,没有其它情况了,轻儿子的最远距离也肯定在它的子节点或者最长链中,所以我们先求出父节点到子节点的最远距离和次远距离,然后利用父节点更新子节点,很难想到啊.
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5.  
  6. using namespace std;
  7.  
  8. const int maxn = ;
  9.  
  10. int n, k,head[maxn],to[maxn * ],nextt[maxn * ],w[maxn * ],tot = ,ner[maxn],son[maxn];
  11. long long mind[maxn],maxd[maxn],secd[maxn],d[maxn],sum;
  12. bool flag[maxn],vis[maxn];
  13.  
  14. void add(int x, int y, int z)
  15. {
  16. w[tot] = z;
  17. to[tot] = y;
  18. nextt[tot] = head[x];
  19. head[x] = tot++;
  20. }
  21.  
  22. bool dfs1(int x) //找树
  23. {
  24. vis[x] = ;
  25. for (int i = head[x]; i; i = nextt[i])
  26. {
  27. int v = to[i];
  28. if (!vis[v])
  29. {
  30. if (dfs1(v))
  31. {
  32. flag[x] = ;
  33. sum += w[i];
  34. }
  35. }
  36. }
  37. return flag[x];
  38. }
  39.  
  40. void dfs2(int x) //找最短距离
  41. {
  42. vis[x] = ;
  43. if (flag[x])
  44. ner[x] = x;
  45. for (int i = head[x]; i; i = nextt[i])
  46. {
  47. int v = to[i];
  48. if (!vis[v] && !flag[v])
  49. {
  50. mind[v] = mind[x] + w[i];
  51. ner[v] = ner[x];
  52. }
  53. if (!vis[v])
  54. dfs2(v);
  55. }
  56. }
  57.  
  58. long long dfs3(int x) //最长距离+次长距离
  59. {
  60. vis[x] = ;
  61. for (int i = head[x]; i; i = nextt[i])
  62. {
  63. int v = to[i];
  64. if (!vis[v] && flag[v])
  65. {
  66. long long t = dfs3(v) + w[i];
  67. if (t > maxd[x])
  68. {
  69. secd[x] = maxd[x];
  70. maxd[x] = t;
  71. son[x] = v;
  72. }
  73. else
  74. if (t > secd[x])
  75. secd[x] = t;
  76. }
  77. }
  78. return maxd[x];
  79. }
  80.  
  81. void dfs4(int x, long long lmax) //最后的更新
  82. {
  83. vis[x] = ;
  84. for (int i = head[x]; i; i = nextt[i])
  85. {
  86. int v = to[i];
  87. d[x] = max(lmax, maxd[x]);
  88. if (flag[v] && !vis[v])
  89. {
  90. if (v == son[x])
  91. dfs4(v, max(lmax, secd[x]) + w[i]);
  92. else
  93. dfs4(v, max(lmax, maxd[x]) + w[i]);
  94. }
  95. }
  96. }
  97.  
  98. int main()
  99. {
  100. memset(flag, false, sizeof(flag));
  101. scanf("%d%d", &n, &k);
  102. for (int i = ; i < n; i++)
  103. {
  104. int x, y, z;
  105. scanf("%d%d%d", &x, &y, &z);
  106. add(x, y, z);
  107. add(y, x, z);
  108. }
  109. int t;
  110. for (int i = ; i <= k; i++)
  111. {
  112. scanf("%d", &t);
  113. flag[t] = ;
  114. }
  115. dfs1(t);
  116. memset(vis, , sizeof(vis));
  117. dfs2(t);
  118. memset(vis, , sizeof(vis));
  119. dfs3(t);
  120. memset(vis, , sizeof(vis));
  121. dfs4(t, );
  122. for (int i = ; i <= n; i++)
  123. printf("%lld\n", sum * + mind[i] - d[ner[i]]);
  124.  
  125. return ;
  126. }

bzoj3743 [Coci2015]Kamp 常州模拟赛d6t2的更多相关文章

  1. 常州模拟赛d4t1 立方体

    题目描述 立方体有 6 个面,每个面上有一只奶牛,每只奶牛都有一些干草.为了训练奶牛的合作精神,它 们在玩一个游戏,每轮:所有奶牛将自己的干草分成 4 等份,分给相邻的 4 个面上的奶牛. 游戏开始, ...

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

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

  3. bzoj3743: [Coci2015]Kamp

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

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

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

  5. 常州模拟赛d7t3 水管

    分析:第一问还是很好做的,关键是怎么做第二问.我们可以每次删掉最小生成树上的一条边,然后再求一次最小生成树,看边权和大小和原来的是不是一样的,不过这个做法效率很低. 考虑Kruskal算法的原理,每次 ...

  6. 常州模拟赛d6t3 噪音

    FJ有M个牛棚,编号1至M,刚开始所有牛棚都是空的.FJ有N头牛,编号1至N,这N头牛按照编号从小到大依次排队走进牛棚,每一天只有一头奶牛走进牛棚.第i头奶牛选择走进第p[i]个牛棚.由于奶牛是群体动 ...

  7. 常州模拟赛d5t2 mogician

    分析:一个暴力的思想是枚举g,然后枚举每个数ai,看能不能符合要求,这样复杂度是O(nA)的,直接T掉了.也没什么其他的办法了,在暴力的基础上优化一下,优化的关键是要如何快速统计出不满足要求的数的个数 ...

  8. 常州模拟赛d5t1 journalist

    分析:出题人丧心病狂卡spfa......只能用dijkstar+堆优化. 主要的难点是字典序的处理上,一个想法是在做最短路的时候处理,边松弛边记录,比个大小记录最佳答案.具体的思路大概和最短路计数差 ...

  9. 常州模拟赛d4t3 字符串划分

    题目描述 给你一串由小写字母组成的字符串,希望你把它划分成一些小段,使得每一小段字符串中的字母 都不相同,并且希望分的段数尽量少. 然后,把这些小段按字典序排序后输出,中间由一个空格分隔. 例如:字符 ...

随机推荐

  1. 利用基于@AspectJ的AOP实现权限控制

    一. AOP与@AspectJ AOP 是 Aspect Oriented Programming 的缩写,意思是面向方面的编程.我们在系统开发中可以提取出很多共性的东西作为一个 Aspect,可以理 ...

  2. Windows64+Python27下配置matplotlib

    注:转载请注明原作者并附上原文链接! 网上看了很多方法,均遇到这样或者那样的问题导致安装失败,最后自己摸索一条方法,最终安装成功了. 1,首先安装numpy,这个可以选择install安装包,很简单, ...

  3. 洛谷 P2419 [USACO08JAN]牛大赛Cow Contest

    题目背景 [Usaco2008 Jan] 题目描述 N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a p ...

  4. docker配置国内镜像

    1. 配置 root@ros-OptiPlex-3050:~# cat /etc/docker/daemon.json {    "graph": "/mnt/docke ...

  5. 使用JavaScript ES6的新特性计算Fibonacci(非波拉契数列)

    程序员面试系列 Java面试系列-webapp文件夹和WebContent文件夹的区别? 程序员面试系列:Spring MVC能响应HTTP请求的原因? Java程序员面试系列-什么是Java Mar ...

  6. XDU——受教了

    存在的问题还是很多的 GG 突然觉得刷题的目的并不是追求A.我们应该在那个过程中提高代码能力和建立模型解题能力 会的算法会巧妙应用才是王道 吐槽自己两句,写高数了

  7. NASM 之 helloworld1

    SECTION .data msg: db "Hello World!", 0x0a len: equ $-msg SECTION .text global _main kerne ...

  8. java实现中文或其他语言及标点符号等转换成unicode字符串,或unicode的16进制码转换回文字或符号等

    package org.analysisitem20181016.test; public class Code128Test2019052201 { public static final Stri ...

  9. 快学UiAutomator创建第一个实例

    工具准备 一.准备好java环境(JDK)和安卓环境(SDK.ADT)jdk1.6+ \eclipse\SDK \ADT详情百度,安装java环境 二.打开eclipse 三.创建步骤: 右键新建== ...

  10. Jarvis OJ-Level4

    借助DynELF实现无libc的漏洞利用小结 #!/usr/bin/env python # coding:utf-8 from pwn import * elf = ELF('level4') wr ...