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

  然后由父亲答案还原。因为上面的dp用到了max似乎不太好搞,于是记录一下最大值是用了哪棵子树以及次大值就行了。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. using namespace std;
  8. int read()
  9. {
  10. int x=,f=;char c=getchar();
  11. while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
  12. while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
  13. return x*f;
  14. }
  15. #define N 500010
  16. #define ll long long
  17. int n,m,a[N],id[N],p[N],size[N],t=;
  18. ll f[N],f2[N],g[N];
  19. bool flag[N];
  20. struct data{int to,nxt,len;
  21. }edge[N<<];
  22. void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
  23. inline ll noback(int x,int y,int z){return g[x]-g[y]+f[y]-z;}
  24. void dfs(int k,int from)
  25. {
  26. size[k]=flag[k];
  27. for (int i=p[k];i;i=edge[i].nxt)
  28. if (edge[i].to!=from)
  29. {
  30. dfs(edge[i].to,k);
  31. size[k]+=size[edge[i].to];
  32. if (size[edge[i].to]) g[k]+=g[edge[i].to]+(edge[i].len<<);
  33. }
  34. f[k]=f2[k]=g[k];
  35. for (int i=p[k];i;i=edge[i].nxt)
  36. if (edge[i].to!=from&&size[edge[i].to])
  37. {
  38. ll x=noback(k,edge[i].to,edge[i].len);
  39. if (x<f[k]) f2[k]=f[k],f[k]=x,id[k]=edge[i].to;
  40. else if (x<f2[k]) f2[k]=x;
  41. }
  42. }
  43. void getans(int k,int from)
  44. {
  45. for (int i=p[k];i;i=edge[i].nxt)
  46. if (edge[i].to!=from)
  47. {
  48. if (size[edge[i].to])
  49. {
  50. if (size[edge[i].to]<m)
  51. {
  52. ll x=f[k],y=g[k];
  53. g[k]-=g[edge[i].to]+(edge[i].len<<);
  54. if (id[k]==edge[i].to) f[k]=f2[k]-(g[edge[i].to]+(edge[i].len<<));
  55. else f[k]=f[k]-(g[edge[i].to]+(edge[i].len<<));
  56. g[edge[i].to]=y;
  57. if (noback(edge[i].to,k,edge[i].len)<f[edge[i].to]+g[k]+(edge[i].len<<))
  58. f2[edge[i].to]=f[edge[i].to]+g[k]+(edge[i].len<<),id[edge[i].to]=k,f[edge[i].to]=noback(edge[i].to,k,edge[i].len);
  59. else f[edge[i].to]+=g[k]+(edge[i].len<<),f2[edge[i].to]=min(f2[edge[i].to]+g[k]+(edge[i].len<<),noback(edge[i].to,k,edge[i].len));
  60. f[k]=x,g[k]=y;
  61. }
  62. }
  63. else g[edge[i].to]=g[k]+(edge[i].len<<),f[edge[i].to]=f[k]+edge[i].len;
  64. getans(edge[i].to,k);
  65. }
  66. }
  67. int main()
  68. {
  69. #ifndef ONLINE_JUDGE
  70. freopen("bzoj3743.in","r",stdin);
  71. freopen("bzoj3743.out","w",stdout);
  72. const char LL[]="%I64d\n";
  73. #else
  74. const char LL[]="%lld\n";
  75. #endif
  76. n=read(),m=read();
  77. for (int i=;i<n;i++)
  78. {
  79. int x=read(),y=read(),z=read();
  80. addedge(x,y,z),addedge(y,x,z);
  81. }
  82. for (int i=;i<=m;i++) flag[read()]=;
  83. dfs(,);
  84. getans(,);
  85. for (int i=;i<=n;i++) printf(LL,f[i]);
  86. return ;
  87. }

BZOJ3743 COCI2015Kamp(树形dp)的更多相关文章

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

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

  2. 树形dp专题总结

    树形dp专题总结 大力dp的练习与晋升 原题均可以在网址上找到 技巧总结 1.换根大法 2.状态定义应只考虑考虑影响的关系 3.数据结构与dp的合理结合(T11) 4.抽直径解决求最长链的许多类问题( ...

  3. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  4. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  5. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  6. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  7. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  8. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  9. POJ2342 树形dp

    原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...

  10. hdu1561 The more, The Better (树形dp+背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...

随机推荐

  1. DSP5509项目之用FFT识别钢琴音调(4)之麦克风输入和Line in输入

    1. 麦克风输入需要修改的内容,之前的版本是LINE IN的输入.实现功能,检测麦克风的输入,并且同时在耳机里面播放. #include <csl.h> #include <csl_ ...

  2. 【RAC搭建报错】libcap.so.1:cannot open shared object file

    原文参考:http://blog.csdn.net/siyanyanyanyai/article/details/45306595 http://orax.blog.sohu.com/26207226 ...

  3. HTML基本代码教学,第二天

    HTML 咱们今天来看一下咱们这HTML能做些什么,例如下图(最低级的小实验) 咱们来看一下图片的最左上角<head> <title></ title></ ...

  4. MES与ERP的区别(转)

    MES和ERP有很大的不同,主要体现在以下几个方面: 1.管理的目标不同 ERP的重点在于财务,也就是从财务的角度出发来对企业的资源进行计划,相关的模块也是以财务为核心的展开,最终的管理数据也是集中到 ...

  5. info信息的获取

    一.绝对路径(_SERVER[“SCRIPT_FILENAME”])这个是最常用,也是最有效的一个办法,找到phpinfo()页面可以直接找到网站的绝对路径,对于写shell和信息搜集是必不可少的.二 ...

  6. qt cout输出中文乱码解决记录

    工具 -> 选项-> 文本编辑器-> 行为 -> 文件编码->默认编码改为System 乱码原因: 默认用utf-8编码,控制台默认gbk编码,编码不一致导致的乱码

  7. python爬取淘宝华为手机

    import re from selenium import webdriver from selenium.common.exceptions import TimeoutException fro ...

  8. Office365创建通讯组

    Office365创建通讯组 命令 new-DistributionGroup -Name 'test' -Members tom@msazure.cn 结果 命令 new-DistributionG ...

  9. PKI(Public Key Infrastucture)介绍

    PKI(Public Key Infrastucture)介绍 根据Wikipedia PKI词条整理. PKI(Public Key Infrastucture)是一系列的规则.策略以及过程,可以用 ...

  10. Python Pygame(5)绘制基本图形

    最近很火一些简单图形构成的小游戏,这里介绍一些绘制图形的函数. 1.绘制矩形 rect(Surface,color,Rect,width=0) 第一个参数指定矩形绘制到哪个Surface对象上 第二个 ...