[Computer] AcWing325

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:

  1. 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
  2. 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

 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 }
AC Code

 

Guess you like

Origin www.cnblogs.com/shl-blog/p/11332726.html