Description
Given a tree, find a point each to reach the farthest distance is the number
Solution
Tree dp
We use the idea of a "second scan and change root law", first assume that a node is the root, then there is a tree root in the tree once dp obtained from each node in its subtree furthest away and times distance, denoted by sum1, sum2
We define ans [i] represents a rooted tree case, starting from the current i in the tree, its sub-tree node to the non-maximum distance is how much, then this point the answer is $ max \ {ans [i] , sum1 [i] \} $
Then we consider the "change root"
Suppose that the current node father ans has been correctly calculated, then for the current node, there are so few cases:
- Sum1 without their father's current node, then the maximum value of the current node is ans + ans + sum1 current node from its father and his father's father from the father of the current node and
- After his father's sum1 the current node, then the current node ans is its father sum2 + current node distance with his father and his father ans + current maximum distance from the node with his father
We dfs twice this tree, to complete dp
Time complexity is $ O (n) $
Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 10010; 4 int n; 5 struct node { 6 int nxt, to, dis; 7 } a[maxn << 1]; 8 int head[maxn], num; 9 inline void add(int from, int to, int dis) { 10 a[++num].nxt = head[from]; 11 a[num].to = to; 12 a[num].dis = dis; 13 head[from] = num; 14 } 15 int sum1[maxn], sum2[maxn], ans[maxn]; 16 int dfs(int now, int fa) { 17 for (register int i = head[now]; i; i = a[i].nxt) { 18 int to = a[i].to; 19 if (to == fa) continue ; 20 sum2[now] = max(sum2[now], dfs(to, now) + a[i].dis); 21 if (sum2[now] > sum1[now]) swap(sum2[now], sum1[now]); 22 } 23 return sum1[now]; 24 } 25 void dp(int now, int fa) { 26 for (register int i = head[now]; i; i = a[i].nxt) { 27 int to = a[i].to; 28 if (to == fa) continue ; 29 if (sum1[to] + a[i].dis == sum1[now]) { 30 ans[to] = max(sum2[now] + a[i].dis, a[i].dis + ans[now]); 31 } 32 else { 33 ans[to] = max(sum1[now] + a[i].dis, a[i].dis + ans[now]); 34 } 35 dp(to, now); 36 } 37 } 38 int main() { 39 while (~scanf("%d", &n)) { 40 num = 0; 41 memset(head, 0, sizeof(head)); 42 for (register int i = 2; i <= n; ++i) { 43 int x, v; 44 scanf("%d%d", &x, &v); 45 add(i, x, v); add(x, i, v); 46 } 47 memset(sum1, 0, sizeof(sum1)); 48 memset(sum2, 0, sizeof(sum2)); 49 memset(ans, 0, sizeof(ans)); 50 dfs(1, 1); 51 dp(1, 1); 52 for (register int i = 1; i <= n; ++i) 53 printf("%d\n", max(ans[i], sum1[i])); 54 } 55 return 0; 56 }