首页 > 其他 > 详细

HDU 2196 computer

时间:2015-10-13 09:10:38      阅读:415      评论:0      收藏:0      [点我收藏+]

传送门

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

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. 
技术分享


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
 
----------------------------------------------------
Solution:
 这道题要求的是从树上一点出发的最长路。考虑有根树,不难想到,从树上一点u出发的最长路必然是下述两种情况之一:
(1)第一步向下走,(一直向下,走到某叶子节点)
(2)第一步向上走。
考虑树形DP:
dp[0][u] : 从节点u向下走的最长路径
dp[1][u] : 从节点u向下走的次长路径
这里,次长路径的含义是:与某条选定的最长路径不重合的路径中最长的路径。
dp[2][u] : 从节点u第一步向上走所能获得的最长路径
注意:
在dp[0][u], dp[1][u]的含义说明中没有强调从节点u第一步向下走,这是由于若第一步向下走,就要一直向下走。
考虑如何转移
对于节点u,考虑u的所有子节点v,用dp[0][v]来更新dp[0][u], dp[1][u]。
至于dp[2][u], 仍考虑两种情况:
(1)第二步向下走, 这样便转移到u的父亲节点f第一步向下走的情况。
这时还要考虑用dp[0][f]还是dp[1][f]来更新dp[2][u]:
如果从f第一步走到u能走出一条从f向下的最长路,就用dp[1][f]来更新dp[2][u],否则用dp[0][f]。
(2)第二步仍向上走,这样便转移到f第一步向上走的情况,即dp[2][f]。
------------------------------------------------------------------------------------------------------------------
Implementation:
#include <bits/stdc++.h>
using namespace std;

const int N(1e4+5);
//dp[0][u]:u到其后代的最长路
//dp[1][u]:u到其后代的次长路
int dp[3][N];
typedef pair<int,int> E;
vector<E> g[N];
//第一步向下走(一直向下走)
void dfs1(int u, int f){
    dp[0][u]=dp[1][u]=0;
    for(int i=0; i<g[u].size(); i++){
        int &v=g[u][i].first, &c=g[u][i].second;
        if(v==f) continue;
        dfs1(v, u);
        if(dp[0][u]<dp[0][v]+c){
            //注意更新dp[0][u]和dp[1][u]的顺序
            dp[1][u]=dp[0][u];
            dp[0][u]=dp[0][v]+c;
        }
        else dp[1][u]=max(dp[1][u], dp[0][v]+c);
    }
}
//第一步向上走
void dfs2(int u, int f){
    for(int i=0; i<g[u].size(); i++){
        int &v=g[u][i].first, &c=g[u][i].second;
        if(v==f) continue;
        //第二步向下走
        dp[2][v]=0;
        if(dp[0][u]==dp[0][v]+c){
            dp[2][v]=max(dp[2][v], dp[1][u]+c);
        }
        else{
            dp[2][v]=max(dp[2][v], dp[0][u]+c);
        }
        //第二步向上走(转移到u的第一步向上走)
        dp[2][v]=max(dp[2][v], dp[2][u]+c);
        dfs2(v, u);
    }
}
int main(){
    for(int n; ~scanf("%d", &n);){
        for(int i=1; i<=n; ++i) g[i].clear();
        for(int u=2, v, c; u<=n; ++u){
            scanf("%d%d", &v, &c); 
            g[u].push_back({v, c});
            g[v].push_back({u, c});
        }
        dfs1(1, 1);
        dp[2][1]=0;
        dfs2(1, 1);
        for(int i=1; i<=n; i++)
            printf("%d\n", max(dp[0][i], dp[2][i]));
    }
}

 

HDU 2196 computer

原文:http://www.cnblogs.com/Patt/p/4873462.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!