给出一棵树,边有权值,求出离每一个节点最远的点的距离

树形DP,经典题

本来这道题是无根树,可以随意选择root,

但是根据输入数据的方式,选择root=1明显可以方便很多。

我们先把边权转化为点权,放在数组cost中

令tree(i)表示以节点i为根的子树

对于节点i,离该节点最远的点要不就是在tree(i)中,要不就是在father(i)上面

令:

dp[i][1] : 在子树tree(i)中,离i最远的距离

dp[i][2] : 在子树tree(i)中,离i第二远的距离 (递推的时候需要)

dp[i][0] : 在树tree(root)-tree(i)中,离i最远的距离

son[i] : 在子树tree(i)中,离i最远的点是在tree(son[i])中,即最远路径经过节点son[i]

则对于每一个i,离i最远的距离=max(dp[i][0],dp[i][1])

流程:

0.链式前向星建树

1.dfs1,确定dp[i][1]

2.dfs2,确定dp[i][2]

dfs1和dfs2都很简单

3.dfs3,递推确定dp[i][0]

  1. #include<cstdio>
  2. #include<cstring>
  3.  
  4. using namespace std;
  5.  
  6. const int maxn=+;
  7. const int inf=0x3f3f3f3f;
  8.  
  9. inline int max(int a,int b)
  10. {
  11. return a>b?a:b;
  12. }
  13.  
  14. struct Edge
  15. {
  16. int to,next;
  17. };
  18. Edge edge[maxn];
  19. int head[maxn];
  20. int tot;
  21. int cost[maxn];
  22. int son[maxn];
  23. int dp[maxn][];
  24.  
  25. void init()
  26. {
  27. memset(head,-,sizeof head);
  28. tot=;
  29. memset(dp,,sizeof dp);
  30. memset(son,-,sizeof son);
  31. }
  32.  
  33. void addedge(int u,int v)
  34. {
  35. edge[tot].to=v;
  36. edge[tot].next=head[u];
  37. head[u]=tot++;
  38. }
  39.  
  40. void solve(int n);
  41. void dfs1(int u,int pre);
  42. void dfs2(int u,int pre);
  43. void dfs3(int u,int pre);
  44.  
  45. int main()
  46. {
  47. int n;
  48. while(~scanf("%d",&n))
  49. {
  50. init();
  51. cost[]=;
  52. for(int i=;i<=n;i++)
  53. {
  54. int u;
  55. scanf("%d %d",&u,&cost[i]);
  56. addedge(u,i);
  57. }
  58. solve(n);
  59. }
  60. return ;
  61. }
  62.  
  63. void solve(int n)
  64. {
  65. dfs1(,-);
  66. dfs2(,-);
  67. dp[][]=;
  68. dfs3(,-);
  69.  
  70. for(int i=;i<=n;i++)
  71. {
  72. printf("%d\n",max(dp[i][],dp[i][]));
  73. }
  74. return ;
  75. }
  76.  
  77. void dfs1(int u,int pre)
  78. {
  79. for(int i=head[u];~i;i=edge[i].next)
  80. {
  81. int v=edge[i].to;
  82. dfs1(v,u);
  83. if(dp[v][]+cost[v]>dp[u][])
  84. {
  85. dp[u][]=dp[v][]+cost[v];
  86. son[u]=v;
  87. }
  88. }
  89. }
  90.  
  91. void dfs2(int u,int pre)
  92. {
  93. for(int i=head[u];~i;i=edge[i].next)
  94. {
  95. int v=edge[i].to;
  96. dfs2(v,u);
  97. if(v==son[u])
  98. continue;
  99. if(dp[v][]+cost[v]>dp[u][])
  100. dp[u][]=dp[v][]+cost[v];
  101. }
  102. }
  103.  
  104. void dfs3(int u,int pre)
  105. {
  106. for(int i=head[u];~i;i=edge[i].next)
  107. {
  108. int v=edge[i].to;
  109. if(v==son[u])
  110. {
  111. dp[v][]=max(dp[u][],dp[u][])+cost[v];
  112. }
  113. else
  114. {
  115. dp[v][]=max(dp[u][],dp[u][])+cost[v];
  116. }
  117. dfs3(v,u);
  118. }
  119. }

HDU 2196 Computer 树形DP 经典题的更多相关文章

  1. HDU 2196 Computer 树形DP经典题

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...

  2. hdu 2196 Computer 树形dp模板题

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  3. hdu 2196 Computer(树形DP经典)

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  4. HDU 2196.Computer 树形dp 树的直径

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  5. hdu 2196 Computer(树形DP)

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  6. 51nod 1353 树 | 树形DP经典题!

    51nod 1353 树 | 树形DP好题! 题面 切断一棵树的任意条边,这棵树会变成一棵森林. 现要求森林中每棵树的节点个数不小于k,求有多少种切法. 数据范围:\(n \le 2000\). 题解 ...

  7. POJ 1155 TELE 背包型树形DP 经典题

    由电视台,中转站,和用户的电视组成的体系刚好是一棵树 n个节点,编号分别为1~n,1是电视台中心,2~n-m是中转站,n-m+1~n是用户,1为root 现在节点1准备转播一场比赛,已知从一个节点传送 ...

  8. HDU 2196 Computer (树dp)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2196 给你n个点,n-1条边,然后给你每条边的权值.输出每个点能对应其他点的最远距离是多少 ...

  9. HDU - 2196(树形DP)

    题目: A school bought the first computer some time ago(so this computer's id is 1). During the recent ...

随机推荐

  1. C#中正则表达式的使用

    目前为止,许多编程语言和工具都包含对正则表达式的支持,C#也不例外,C#基础类库中包含有一个命名空间(System.Text.RegularExpressions)和一系列可以充分发挥规则表达式威力的 ...

  2. createdb test时报global/pg_filenode.map不存在

    实际上是存在的,看到说是ipv6占用了5432的端口号,看了一下的确是,将ipv6关闭重启系统即可. 下面是关闭ipv6的方法: 确认IPV6是否开启 在Linux下确认IPv6是否已经被启用,可以从 ...

  3. Oracle数据库——SQL高级查询

    一.涉及内容 1.掌握SELECT语句的多表连接查询. 2.掌握SELECT语句的子查询. 二.具体操作 (一)根据Oracle数据库scott方案下的emp表和dept表,完成下列操作: 1.查询所 ...

  4. Openjudge计算概论-DNA排序

    /*===================================== DNA排序 总时间限制: 1000ms 内存限制: 65536kB 描述 给出一系列基因序列,由A,C,G,T四种字符组 ...

  5. LINUX系统下PHP显示空白页

    因为手工转移,文件所属用户及用户组是root,所以需要把网站程序及数据库都改成对应用户组:如www和mysql. 更改目录所属用户执行命令: chown -R 用户.用户组 目录名, 如:chown ...

  6. 百度ue富文本编辑器setContent方法报错初始化加载内容失败解决办法

    解决方案: 不能创建editor之后马上使用ueditor.setContent('文本内容');要等到创建完成之后才可以使用 ueditor.addListener("ready" ...

  7. python exec

    exec官方声明This statement supports dynamic execution of Python code. exec语句用来执行储存在字符串或文件中的python语句.exec ...

  8. ibats注意

    <isNotEqual property="id" compareValue="0" prepend="and">id=#id# ...

  9. BI案例:KPI在商业智能中的应用(ZT)

    KPI(Key Performance Indication)即关键业绩指标,是通过对组织内部某一流程的输入端.输出端的关键参数进行设置.取样.计算.分析,衡量流程绩效的一种目标式量化管理指标,是把企 ...

  10. Android 使用Telephony API

    Android 使用Telephony API public class TelephonyDemo extends Activity { TextView textOut; TelephonyMan ...