1. 程式人生 > >HDU2196 Computer樹形dp

HDU2196 Computer樹形dp

Problem Description

A school bought the first computer some time ago(so this computer’s id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information. img

Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.

Input

Input file contains multiple test

cases.In each case there is natural number N (N<=10000) in the first line, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space.

Output

For each case output N lines. i-th line must contain number Si for i-th computer (1<=i<=N).

Sample Input

5
1 1
2 1
3 1
1 1

Sample Output

3
2
3
4
4

​ 翻譯成漢語,就是給你n個點,再給n - 1行每行兩個整數a, b,代表第i個電腦和a相連距離為b。最後輸出每臺電腦距離最遠電腦的距離

思路:

​ 這題我們可以把圖轉化為樹,可以說是樹形dp吧。我們通過第一遍dfs由葉到根遞迴計算每個節點作為根節點的子樹中,與該節點距離最遠和次遠的距離與兒子節點。再通過第二遍dfs由根到葉遞迴計算每個節點往上走(非該子樹)節點的最長距離。最後我們遍歷每個節點,只需要比較該節點作為根節點的子樹中的最長距離與往上走的最大值,取較大值即為答案。

程式碼:

#include <stdio.h>
#include <vector>
#include <algorithm>
#include <string.h>
#define N 10005
#define mem(a) memset(a, 0, sizeof(a));
using namespace std;

struct node {
    int son, val;
};

struct gold {
    int maxx, son;
};

int n;
vector<node>point[N];
gold maxn[N][3];  //0最大值 1次大值 2父最大值
int pre[N];

void init() {
    int a, b;
    node c;
    mem(maxn);
    for (int i = 1; i <= n; i++) {
        pre[i] = i;
        point[i].clear();
    }
    for (int i = 2; i <= n; i++) {
        scanf("%d%d", &a, &b);
        pre[i] = a;
        c.son = i;
        c.val = b;
        point[a].push_back(c);
    }
}

void dfs(int inx) {
    for (int i = 0; i < point[inx].size(); i ++) {
        node son = point[inx][i];
        dfs(son.son);
        if(maxn[inx][0].maxx < son.val + maxn[son.son][0].maxx) {
            maxn[inx][1].maxx = maxn[inx][0].maxx;
            maxn[inx][1].son = maxn[inx][0].son;
            maxn[inx][0].maxx = son.val + maxn[son.son][0].maxx;
            maxn[inx][0].son = son.son;
        } else if(maxn[inx][1].maxx < son.val + maxn[son.son][0].maxx) {
            maxn[inx][1].maxx = son.val + maxn[son.son][0].maxx;
            maxn[inx][1].son = son.son;
        }
    }
}

void dfs1(int inx) {
    int father = pre[inx];
    if(inx != 1) {
        int t;
        for(int i = 0; i < point[father].size(); i++) {
            if(point[father][i].son == inx) {
                t = point[father][i].val;
                break;
            }
        }
        if(maxn[father][0].son == inx) {
            maxn[inx][2].son = father;
            maxn[inx][2].maxx = t + max(maxn[father][1].maxx, maxn[father][2].maxx);
        } else {
            maxn[inx][2].son = father;
            maxn[inx][2].maxx = t + max(maxn[father][0].maxx, maxn[father][2].maxx);
        }
    }
    for (int i = 0; i < point[inx].size(); i++) {
        dfs1(point[inx][i].son);
    }
}

int main () {
    while (scanf("%d", &n) == 1) {
        int ans;
        init();
        dfs(1);
        dfs1(1);
        for (int i = 1; i <= n; i++) {
            ans = max(maxn[i][0].maxx, maxn[i][2].maxx);
            printf("%d\n", ans);
        }
    }
    return 0;
}

如果有寫的不對或者不全面的地方 可通過主頁的聯絡方式進行指正,謝謝