题意:求树每个点到其他点的最远距离。
思路:选择一点作为树的根,令dp[u][0]为点u从子树中取得的最长距离,dp[u][1]为点u从子树中取得的次长距离,dp[u][2]为从父亲节点取得的最长距离
则最远距离为dp[u][0]或dp[u][2]
dp[u][0]和dp[u][1]比较简单,一次深搜求得
dp[u][2]有两种情况,设a为u的父亲节点
当u在a子树取得最长距离的路径上时,dp[u][2] = max(dp[a][1], dp[a][2]) + dist(a,u);
当u不在a子树取得最长距离的路径上时,dp[u][2] = max(dp[a][0], dp[a][2]) + dist(a,u);
思路:选择一点作为树的根,令dp[u][0]为点u从子树中取得的最长距离,dp[u][1]为点u从子树中取得的次长距离,dp[u][2]为从父亲节点取得的最长距离
则最远距离为dp[u][0]或dp[u][2]
dp[u][0]和dp[u][1]比较简单,一次深搜求得
dp[u][2]有两种情况,设a为u的父亲节点
当u在a子树取得最长距离的路径上时,dp[u][2] = max(dp[a][1], dp[a][2]) + dist(a,u);
当u不在a子树取得最长距离的路径上时,dp[u][2] = max(dp[a][0], dp[a][2]) + dist(a,u);

1 #include <cstdio>
2 #include <cstring>
3 #define N 10005
4
5 int dp[N][3];
6 int head[N], mark[N], eNum;
7 struct Edge
8 {
9 int e, next, w;
10 }edge[N*2];
11
12 int max2(int x, int y)
13 {
14 return x > y ? x : y;
15 }
16
17 void init(int n)
18 {
19 memset(head, -1, sizeof(head));
20 memset(mark, 0, sizeof(mark));
21 eNum = 0;
22 }
23
24 void AddEdge(int u, int v, int w)
25 {
26 edge[eNum].e = v;
27 edge[eNum].w = w;
28 edge[eNum].next = head[u];
29 head[u] = eNum++;
30 }
31
32 void input(int n)
33 {
34 int v, w;
35 for(int u=2; u<=n; u++)
36 {
37 scanf("%d%d",&v, &w);
38 AddEdge(u, v, w);
39 AddEdge(v, u, w);
40 }
41 }
42
43 void dfs(int u, int pre)
44 {
45 dp[u][0] = 0; dp[u][1] = 0;
46 for(int i=head[u]; i!=-1; i=edge[i].next)
47 {
48 int v = edge[i].e, w = edge[i].w;
49 if(v == pre) continue;
50 dfs(v, u);
51 if(dp[u][0]<dp[v][0]+w)
52 {
53 dp[u][1] = dp[u][0]; //先将最长距离赋给次长距离,再更新最长距离(低级错误)
54 dp[u][0] = dp[v][0] + w;
55 mark[u] = v;
56 }
57 else if(dp[u][1]<dp[v][0]+w)
58 dp[u][1] = dp[v][0] + w;
59 }
60 }
61
62 void solve(int u, int pre)
63 {
64 for(int i=head[u]; i!=-1; i=edge[i].next)
65 {
66 int v = edge[i].e, w = edge[i].w;
67 if(pre == v) continue;
68
69 if(mark[u]==v)
70 dp[v][2] = max2(dp[u][1], dp[u][2]) + w;
71 else
72 dp[v][2] = max2(dp[u][0], dp[u][2]) + w;
73 solve(v, u);
74 }
75 }
76
77 int main()
78 {
79 int n;
80 while(scanf("%d",&n)!=EOF)
81 {
82 init(n);
83 input(n);
84 dfs(1, 0);
85 dp[1][2] = 0;
86 solve(1, 0);
87
88 for(int i=1; i<=n; i++)
89 printf("%d ",max2(dp[i][0],dp[i][2]));
90 }
91 return 0;
92 }
2 #include <cstring>
3 #define N 10005
4
5 int dp[N][3];
6 int head[N], mark[N], eNum;
7 struct Edge
8 {
9 int e, next, w;
10 }edge[N*2];
11
12 int max2(int x, int y)
13 {
14 return x > y ? x : y;
15 }
16
17 void init(int n)
18 {
19 memset(head, -1, sizeof(head));
20 memset(mark, 0, sizeof(mark));
21 eNum = 0;
22 }
23
24 void AddEdge(int u, int v, int w)
25 {
26 edge[eNum].e = v;
27 edge[eNum].w = w;
28 edge[eNum].next = head[u];
29 head[u] = eNum++;
30 }
31
32 void input(int n)
33 {
34 int v, w;
35 for(int u=2; u<=n; u++)
36 {
37 scanf("%d%d",&v, &w);
38 AddEdge(u, v, w);
39 AddEdge(v, u, w);
40 }
41 }
42
43 void dfs(int u, int pre)
44 {
45 dp[u][0] = 0; dp[u][1] = 0;
46 for(int i=head[u]; i!=-1; i=edge[i].next)
47 {
48 int v = edge[i].e, w = edge[i].w;
49 if(v == pre) continue;
50 dfs(v, u);
51 if(dp[u][0]<dp[v][0]+w)
52 {
53 dp[u][1] = dp[u][0]; //先将最长距离赋给次长距离,再更新最长距离(低级错误)
54 dp[u][0] = dp[v][0] + w;
55 mark[u] = v;
56 }
57 else if(dp[u][1]<dp[v][0]+w)
58 dp[u][1] = dp[v][0] + w;
59 }
60 }
61
62 void solve(int u, int pre)
63 {
64 for(int i=head[u]; i!=-1; i=edge[i].next)
65 {
66 int v = edge[i].e, w = edge[i].w;
67 if(pre == v) continue;
68
69 if(mark[u]==v)
70 dp[v][2] = max2(dp[u][1], dp[u][2]) + w;
71 else
72 dp[v][2] = max2(dp[u][0], dp[u][2]) + w;
73 solve(v, u);
74 }
75 }
76
77 int main()
78 {
79 int n;
80 while(scanf("%d",&n)!=EOF)
81 {
82 init(n);
83 input(n);
84 dfs(1, 0);
85 dp[1][2] = 0;
86 solve(1, 0);
87
88 for(int i=1; i<=n; i++)
89 printf("%d ",max2(dp[i][0],dp[i][2]));
90 }
91 return 0;
92 }