[HDOJ2196]Computer (树直径, 树DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196

给一棵树,求树上各点到某点的距离中最长的距离。注意每个点都要求。

和普通求树的直径不一样,要求每一个点,点的数量是10000因此每一个点都跑一次dfs就会超时。因此先随便dfs一个点,找到一个点后以此点为原点再找距离它最远的点,再找一次即可找到树直径两端的点。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <fstream>
 8 #include <cassert>
 9 #include <cstdio>
10 #include <bitset>
11 #include <vector>
12 #include <deque>
13 #include <queue>
14 #include <stack>
15 #include <ctime>
16 #include <set>
17 #include <map>
18 #include <cmath>
19 
20 using namespace std;
21 
22 typedef struct Edge {
23     int v, w;
24     int next;
25 }Edge;
26 const int maxn = 10010;
27 int n, ecnt;
28 int head[maxn];
29 Edge e[maxn*maxn];
30 int dp[maxn];
31 int ed, lp;
32 
33 void init() {
34     memset(head, -1, sizeof(head));
35     ecnt = 0;
36 }
37 
38 void adde(int u, int v, int w) {
39     e[ecnt].v = v;
40     e[ecnt].w = w;
41     e[ecnt].next = head[u];
42     head[u] = ecnt++;
43 }
44 
45 void dfs(int u, int pre, int len) {
46     if(len > lp) {
47         lp = len;
48         ed = u;
49     }
50     for(int i = head[u]; ~i; i=e[i].next) {
51         if(e[i].v == pre) continue;
52         dfs(e[i].v, u, len + e[i].w);
53         dp[e[i].v] = max(dp[e[i].v], len+e[i].w);
54     }
55 }
56 
57 int main() {
58     // freopen("in", "r", stdin);
59     int v, w;
60     while(~scanf("%d", &n)) {
61         init();
62         for(int i = 2; i <= n; i++) {
63             scanf("%d %d", &v, &w);
64             adde(i, v, w);
65             adde(v, i, w);
66         }
67         lp = -1;
68         memset(dp, 0, sizeof(dp));
69         dfs(1, -1, 0);
70         dfs(ed, -1, 0);
71         dfs(ed, -1, 0);
72         for(int i = 1; i <= n; i++) {
73             printf("%d
", dp[i]);
74         }
75     }
76     return 0;
77 }
原文地址:https://www.cnblogs.com/kirai/p/5359079.html