HDU2196:Computer(树形DP)

来源:互联网 发布:安装刷机软件 编辑:程序博客网 时间:2024/05/04 17:04
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. 


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
51 12 13 11 1
 

Sample Output
32344
 


 

题意:给出每台电脑到某台电脑的距离,求出每台电脑所能到达的最长距离

思路:树形dp,先用一次DFS求出每个节点到叶子的最大距离,再来一次DFS更新所有节点即可

 

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;int len;int head[10005],dp[10005],id[10005],dp2[10005],id2[10005];//dp[i],从i往下倒叶子的最大距离//id,最大距离对应的序号//dp2,次大距离//id2,次大序号struct node{    int now,next,len;} tree[20005];void add(int x,int y,int z)//建树{    tree[len].now = y;    tree[len].len = z;    tree[len].next = head[x];    head[x] = len++;    tree[len].now = x;    tree[len].len = z;    tree[len].next = head[y];    head[y] = len++;}void dfs1(int root,int p){    //从节点root往下倒叶子节点的最大距离    //p是root父节点    int i,j,k,tem;    dp[root] = 0;    dp2[root] = 0;    for(i = head[root]; i!=-1; i = tree[i].next)    {        k = tree[i].now;        if(k == p)//不能再找父节点            continue;        dfs1(k,root);        if(dp2[root]<dp[k]+tree[i].len)//比次大的要大        {            dp2[root] = dp[k]+tree[i].len;            id2[root] = k;            if(dp2[root]>dp[root])//次大大于最大,交换其值与id            {                swap(dp2[root],dp[root]);                swap(id2[root],id[root]);            }        }    }}//len为p到root的长度void dfs2(int root,int p){    //从父亲节点开始更新    int i,j,k;    for(i = head[root]; i!=-1; i = tree[i].next)    {        k = tree[i].now;        if(k == p)            continue;        if(k == id[root])//最大距离的序号,对应的是dp[k],多以这里要加次大的        {            if(tree[i].len+dp2[root]>dp2[k])            {                dp2[k] = tree[i].len+dp2[root];                id2[k] = root;                if(dp2[k]>dp[k])                {                    swap(dp2[k],dp[k]);                    swap(id2[k],id[k]);                }            }        }        else        {            if(tree[i].len+dp[root]>dp2[k])            {                dp2[k] = tree[i].len+dp[root];                id2[k] = root;                if(dp2[k]>dp[k])                {                    swap(dp2[k],dp[k]);                    swap(id2[k],id[k]);                }            }        }        dfs2(k,root);    }}int main(){    int n,i,j,x,y;    while(~scanf("%d",&n))    {        len = 0;        memset(head,-1,sizeof(head));        for(i = 2; i<=n; i++)        {            scanf("%d%d",&x,&y);            add(i,x,y);        }        dfs1(1,-1);        dfs2(1,-1);        for(i = 1; i<=n; i++)            printf("%d\n",dp[i]);    }    return 0;}