[关闭]
@Acqua 2019-01-25T02:07:21.000000Z 字数 1308 阅读 988

HDU2196 Computers(Jan. 22th, 2019) 树形DP

动态规划

题目来源

题意

给定一棵个节点的树和边权,求每个节点与其距离最远的点的距离。

思路

,第一遍自下向上更新,求出以为根的子树中与相距最远距离和次远距离,记为
第二遍自上向下更新,求出通过其与父节点连边达到的最远距离,记为
记录的最远距离所属的路径通过,那么如果

代码

  1. // La Pluie
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. using namespace std;
  7. const int N=10005;
  8. struct edge
  9. {
  10. int v,w,next;
  11. }e[N<<1];
  12. int head[N],n,k,dp[N][3];
  13. // dp[u][0]: 以 u 为根的子树内 u 的最大距离
  14. // dp[u][1]: 以 u 为根的子树内 u 的次大距离
  15. // dp[u][2]: u 通过其父亲能达到的最大距离
  16. void adde(int u,int v,int w)
  17. {
  18. e[k]=(edge){v,w,head[u]};
  19. head[u]=k++;
  20. }
  21. void dfs(int u,int f)
  22. {
  23. for(int i=head[u];i!=-1;i=e[i].next)
  24. {
  25. int v=e[i].v;
  26. if(v==f) continue;
  27. dfs(v,u);
  28. int pluie=dp[v][0]+e[i].w;
  29. if(pluie>dp[u][0])
  30. {
  31. dp[u][1]=dp[u][0];
  32. dp[u][0]=pluie;
  33. }
  34. else if(pluie>dp[u][1])
  35. {
  36. dp[u][1]=pluie;
  37. }
  38. }
  39. }
  40. void Dfs(int u,int f)
  41. {
  42. for(int i=head[u];i!=-1;i=e[i].next)
  43. {
  44. int v=e[i].v;
  45. if(v==f) continue;
  46. if(dp[u][0]==dp[v][0]+e[i].w)
  47. {
  48. dp[v][2]=max(dp[u][2],dp[u][1])+e[i].w;
  49. }
  50. else
  51. {
  52. dp[v][2]=max(dp[u][2],dp[u][0])+e[i].w;
  53. }
  54. Dfs(v,u);
  55. }
  56. }
  57. int main()
  58. {
  59. while(~scanf("%d",&n))
  60. {
  61. memset(head,-1,sizeof(head));
  62. memset(dp,0,sizeof(dp));
  63. k=1;
  64. for(int v=2;v<=n;v++){
  65. int u,w;
  66. scanf("%d%d",&u,&w);
  67. adde(u,v,w);
  68. adde(v,u,w);
  69. }
  70. dfs(1,0);
  71. Dfs(1,0);
  72. for(int i=1;i<=n;i++){
  73. printf("%d\n",max(dp[i][0],dp[i][2]));
  74. }
  75. }
  76. return 0;
  77. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注