SGU 149 Computer Network [树形DP]

  求树上的每个节点能到达的最远距离。

  先预处理出每个节点从叶子上来的最大距离和次大距离,并且记录最大距离是从哪个儿子上来的。

  对于每个节点,它能到的最大距离,要不就是走到自己的某个叶子,要不就是走到某个祖先节点然后转弯进入这个祖先的另一个儿子。向下DP,传递不经过这棵子树到该顶点的最大距离。

 

 1 #include <string.h>
 2 #include <stdio.h>
 3 #include <algorithm>
 4 #define MAXN 10001
 5 #define INF 0x3f3f3f3f
 6 using namespace std;
 7 
 8 struct egde{
 9     int v, w, n;
10 }e[MAXN*2];
11 int n, tu, tv, ans;
12 int first[MAXN], es;
13 void addedge(int u, int v, int w){
14     e[es].v = v, e[es].w = w;
15     e[es].n = first[u], first[u] = es++;
16 }
17 int mson[MAXN][2], mdis[MAXN][2], d[MAXN];
18 void dp1(int u, int f){
19     mdis[u][0] = mdis[u][1] = 0, mson[u][0] = mson[u][1] = -1;
20     for (int i = first[u]; i != -1; i = e[i].n) {
21         int v = e[i].v;
22         if (v == f) continue;
23         dp1(v, u);
24         if (mdis[v][0] + e[i].w > mdis[u][1]) mdis[u][1] = mdis[v][0] + e[i].w, mson[u][1] = v;
25         if (mdis[u][1]  > mdis[u][0]) swap(mdis[u][0], mdis[u][1]), swap(mson[u][0], mson[u][1]);
26     }
27 }
28 void dp2(int u, int f, int w){
29     d[u] = max(mdis[u][0], w);
30     for (int i = first[u] ; i != -1; i = e[i].n) {
31         int v = e[i].v;
32         if (v == f) continue;
33         int tmp = (mson[u][0]==v ? mdis[u][1]+e[i].w : mdis[u][0]+e[i].w);
34         dp2(v, u, max(w+e[i].w, tmp));
35     }
36 }
37 int main(){
38     scanf("%d", &n);
39     memset(first, -1, sizeof first); es = 0;
40     for (int i = 2; i <= n; i++) {
41         scanf("%d%d", &tu, &tv);
42         addedge(i, tu, tv);
43         addedge(tu, i, tv);
44     }
45     dp1(1, -1);
46     dp2(1, -1, 0);
47     for (int i = 1; i <= n; i++) printf("%d\n", d[i]);
48     return 0;
49 }
posted @ 2012-09-28 14:01  Burn_E  阅读(344)  评论(0编辑  收藏  举报