HDU 2196 - Computer
Computer
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5935 Accepted Submission(s): 2985
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.split.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
题意:
给你一棵树,求每个节点到叶子节点的最大距离是多少
思路:
假设:求节点2到叶子节点的最大距离,
图片借鉴:http://blog.csdn.net/shuangde800/article/details/9732825
首先,先求2左边(蓝色)这个子树的最大值,再求右边(红色)子树的最大值,
取两者间的最大值,
所以用两个dfs求
第一次DFS求出所有节点在他的子树范围内到叶子节点距离的最大值和第二大的值,
第二次DFS更新从父节点过来的情况就可以了。
需要注意的是:
如果只存最大值的话,判断一个点的从父节点过来的最大值,那么如果他的父节点存的最大值正好是从该点过来的,那么就失去了从父节点过来的状态,所以要记录最大的两个值
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # include <iostream> 2 # include <cstring> 3 using namespace std; 4 const int MAX = 10010; 5 struct Node 6 { 7 int to; 8 int len; 9 int next; 10 }tree[MAX * 2]; 11 int head[MAX]; 12 int tol = 0; 13 14 int Max[MAX]; 15 int sMax[MAX]; 16 int Maxid[MAX]; 17 int sMaxid[MAX]; 18 void add(int a, int b, int len) 19 { 20 tree[tol].to = b; 21 tree[tol].len = len; 22 tree[tol].next = head[a]; 23 head[a] = tol++; 24 25 tree[tol].to = a; 26 tree[tol].len = len; 27 tree[tol].next = head[b]; 28 head[b] = tol++; 29 } 30 void dfs1(int root, int f) 31 { 32 Max[root] = 0; 33 sMax[root] = 0; 34 for(int i = head[root]; i != -1; i = tree[i].next) 35 { 36 int son = tree[i].to; 37 if(son == f) 38 continue; 39 dfs1(son, root); 40 41 if(sMax[root] < Max[son] + tree[i].len) 42 { 43 sMax[root] = Max[son] + tree[i].len; 44 sMaxid[root] = son; 45 if(sMax[root] > Max[root]) 46 { 47 swap(sMax[root], Max[root]); 48 swap(sMaxid[root], Maxid[root]); 49 } 50 } 51 } 52 } 53 void dfs2(int root, int f) 54 { 55 for(int i = head[root]; i != -1; i = tree[i].next) 56 { 57 int son = tree[i].to; 58 if(son == f) 59 continue; 60 if(son == Maxid[root]) 61 { 62 if(tree[i].len + sMax[root] > sMax[son]) 63 { 64 sMax[son] = tree[i].len + sMax[root]; 65 sMaxid[son] = root; 66 if(sMax[son] > Max[son]) 67 { 68 swap(sMax[son], Max[son]); 69 swap(sMaxid[son], Maxid[son]); 70 } 71 } 72 } 73 else 74 { 75 if(tree[i].len + Max[root] > sMax[son]) 76 { 77 sMax[son] = tree[i].len + Max[root]; 78 sMaxid[son] = root; 79 if(sMax[son] > Max[son]) 80 { 81 swap(sMax[son], Max[son]); 82 swap(sMaxid[son], Maxid[son]); 83 } 84 } 85 } 86 dfs2(son, root); 87 } 88 } 89 int main() 90 { 91 int n; 92 while(scanf("%d", &n) != EOF) 93 { 94 memset(head, -1, sizeof(head)); 95 tol = 0; 96 for(int i = 2; i <= n; i++) 97 { 98 int a, len; 99 scanf("%d%d", &a, &len); 100 add(i, a, len); 101 } 102 dfs1(1, -1); 103 dfs2(1, -1); 104 for(int i = 1; i <= n; i++) 105 printf("%d\n", Max[i]); 106 } 107 return 0; 108 }
生命不息,奋斗不止,这才叫青春,青春就是拥有热情相信未来。