您的位置:首页 > 其它

HDU2196:Computer(树形DP)

2013-08-09 17:52 405 查看
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
5
1 1
2 1
3 1
1 1




Sample Output
3
2
3
4
4






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

思路:树形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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: