码迷,mamicode.com
首页 > 其他好文 > 详细

HDU2196 树形DP

时间:2016-08-18 12:43:38      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:

Computer

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5903    Accepted Submission(s): 2963


Problem Description
A school bought the first computer some time ago(so this computer‘s id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information.
技术分享


Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.
 

 

Input
Input file contains multiple test cases.In each case there is natural number N (N<=10000) in the first line, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space.
 

 

Output
For each case output N lines. i-th line must contain number Si for i-th computer (1<=i<=N).
 

 

Sample Input
5 1 1 2 1 3 1 1 1
 

 

Sample Output
3 2 3 4 4
 

 

Author
scnu
 
题意:
第一台电脑是根节点,给出若干台电脑与电脑之间的距离,问每一台电脑与其他电脑之间的最大距离。
代码:
  1 /*
  2 某一节点的最大距离可以由他的子树中得来也可以由他的父亲得来,如果由他父亲得来,他父亲的最大值可能是从他那
  3 里来的,如果是这样就要用他父亲的次最大值,所以每一节点要找到最大值和次最大值,用两次搜索确定最大值。
  4 */
  5 #include<iostream>
  6 #include<string>
  7 #include<cstdio>
  8 #include<cmath>
  9 #include<cstring>
 10 #include<algorithm>
 11 #include<vector>
 12 #include<iomanip>
 13 #include<queue>
 14 #include<stack>
 15 using namespace std;
 16 int n,head[20010],dp[20010][4];//表示到那个结点,j=0表示到此节点的最大值,j=1表示到此节点的次最大值
 17 //j=2表示到此节点的最大值的情况下的子节点,j=3表示到此节点的次最大值的情况下的子节点。
 18 int lne;
 19 struct node
 20 {
 21     int to,next,val;
 22 }tree[20010];
 23 void add(int u,int v,int w)
 24 {
 25     tree[lne].to=v;
 26     tree[lne].val=w;
 27     tree[lne].next=head[u];
 28     head[u]=lne++;
 29     tree[lne].to=u;
 30     tree[lne].val=w;
 31     tree[lne].next=head[v];
 32     head[v]=lne++;
 33 }
 34 void dfs1(int root,int pre)
 35 {
 36     for(int i=head[root];i!=-1;i=tree[i].next)
 37     {
 38         int son=tree[i].to;
 39         if(son==pre)
 40         continue;
 41         dfs1(son,root);
 42         if(dp[root][0]<dp[son][0]+tree[i].val)
 43         {
 44             dp[root][1]=dp[root][0];//把最大值赋给次最大值
 45             dp[root][3]=dp[root][2];//最大值的子节点给次最大值
 46             dp[root][0]=dp[son][0]+tree[i].val;//赋上新的最大值
 47             dp[root][2]=son;//新最大值的子节点
 48         }
 49         else if(dp[root][1]<dp[son][0]+tree[i].val)
 50         {
 51             dp[root][1]=dp[son][0]+tree[i].val;
 52             dp[root][3]=son;
 53         }
 54     }
 55 }
 56 void dfs2(int root,int pre)
 57 {
 58     for(int i=head[root];i!=-1;i=tree[i].next)
 59     {
 60         int son=tree[i].to;
 61         if(son==pre)
 62         continue;
 63         if(son==dp[root][2])//如果root的最大值是由son点来的,son的最大值就不能被更新位root的最大值,而是
 64                             //root的次最大值
 65         {
 66             if(dp[son][0]<dp[root][1]+tree[i].val)
 67             {
 68                 dp[son][1]=dp[son][0];
 69                 dp[son][3]=dp[son][2];
 70                 dp[son][0]=dp[root][1]+tree[i].val;
 71                 dp[son][2]=root;
 72             }
 73             else if(dp[son][1]<dp[root][1]+tree[i].val)
 74             {
 75                 dp[son][1]=dp[root][1]+tree[i].val;
 76                 dp[son][3]=root;
 77             }
 78         }
 79         else
 80         {
 81             if(dp[son][0]<dp[root][0]+tree[i].val)
 82             {
 83                 dp[son][1]=dp[son][0];
 84                 dp[son][3]=dp[son][2];
 85                 dp[son][0]=dp[root][0]+tree[i].val;
 86                 dp[son][2]=root;
 87             }
 88             else if(dp[son][1]<dp[root][0]+tree[i].val)
 89             {
 90                 dp[son][1]=dp[root][0]+tree[i].val;
 91                 dp[son][3]=root;
 92             }
 93         }
 94         dfs2(son,root);
 95     }
 96 }
 97 int main()
 98 {
 99     int v,w;
100     while(scanf("%d",&n)!=EOF)
101     {
102         lne=0;
103         memset(head,-1,sizeof(head));
104         memset(dp,0,sizeof(dp));
105         for(int i=2;i<=n;i++)
106         {
107             scanf("%d%d",&v,&w);
108             add(i,v,w);
109             dp[i][2]=i;
110             dp[i][3]=i;
111         }
112         dfs1(1,0);
113         dfs2(1,0);
114         for(int i=1;i<=n;i++)
115         {
116             printf("%d\n",dp[i][0]);
117         }
118     }
119     return 0;
120 }

 

HDU2196 树形DP

标签:

原文地址:http://www.cnblogs.com/--ZHIYUAN/p/5783259.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!