HDU 2196 树状dp 求树中节点之间的最长距离
Computer
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3749 Accepted Submission(s): 1892
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.
![](http://acm.hdu.edu.cn/data/images/C128-1005-1.JPG)
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.
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
Recommend
lcy
HDU 2196:
题目意思:
求一棵树中的任意一个点到树中其他的节点的最长距离;
解题思路:
两次dp,第一次dp的时候求出以点i为根的子树中i到其他节点的最长距离,状态转移方程为:
dp[i]=max(dp[son]+w[i][son],dp[i]);
注:在第一次运算的时候,需要把最大值和次大值都记录下来;
第二次dp的时候算从i节点的父亲节点过来的最大值,如果i节点的父亲节点的最大值是从i节点进行状态转移转化过去的,则需要用此时的最大值与父亲节点的次大值加上边权值与原来的最大值比较;
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<vector> 7 using namespace std; 8 const int maxn=10007; 9 int dp[maxn][3]; 10 struct node 11 { 12 int to,cost; 13 }; 14 vector<node> G[maxn]; 15 16 int n; 17 void init() 18 { 19 memset(dp,0,sizeof(dp)); 20 for(int i=0;i<maxn;i++) 21 G[i].clear(); 22 } 23 void slove1(int point,int father) 24 { 25 int big=0,bigger=0; 26 for(int i=0;i<G[point].size();i++) 27 { 28 int v=G[point][i].to; 29 if(v==father) continue; 30 slove1(v,point); 31 if(dp[v][0]+G[point][i].cost>big) 32 { 33 bigger=big; 34 big=dp[v][0]+G[point][i].cost; 35 } 36 else if(dp[v][0]+G[point][i].cost>bigger) bigger=dp[v][0]+G[point][i].cost; 37 } 38 dp[point][0]=big; 39 dp[point][1]=bigger; 40 } 41 void slove2(int point,int father) 42 { 43 int t; 44 for(int i=0;i<G[point].size();i++) 45 { 46 int v=G[point][i].to; 47 if(v==father) continue; 48 if(dp[point][0]==dp[v][0]+G[point][i].cost) t=dp[point][1]; 49 else t=dp[point][0]; 50 dp[v][2]=max(dp[point][2],t)+G[point][i].cost; 51 slove2(v,point); 52 } 53 } 54 int main() 55 { 56 // freopen("in.txt","r",stdin); 57 int a,b; 58 while(~scanf("%d",&n)){ 59 init();node n1; 60 for(int i=2;i<=n;i++) 61 { 62 scanf("%d %d",&a,&b); 63 n1.to=a;n1.cost=b; 64 G[i].push_back(n1); 65 n1.to=i; 66 G[a].push_back(n1); 67 } 68 slove1(1,-1); 69 dp[1][2]=0; 70 slove2(1,-1); 71 for(int i=1;i<=n;i++) 72 printf("%d\n",max(dp[i][2],dp[i][0])); 73 } 74 return 0; 75 }