hdu 2196 Computer

来源:互联网 发布:视频语速加快软件 编辑:程序博客网 时间:2024/05/30 22:57

Computer

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1825    Accepted Submission(s): 895


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
 

Author
scnu
 

Recommend
lcy
 
   我们可以先把它当成一个以任意节点(一般都以编号为1的节点)当根节点做一次dp,dp[i]代表以i为根的子树的最大权值。做完一次后根节点(节点1)肯定已经是最优的了,那么我们现在要想办法更新其他的节点,假如现在要更新节点1的儿子节点son,那么我们首先要计算出除了1到son以外的别的1出发到儿子节点的权值的最大,然后更新一下son目前的值,然后再从son节点继续往下更新,这样就不减少了很多重复计算,最后每个节点都是最优的情况。
#include <iostream>#include<stdio.h>#include<string.h>using namespace std;struct node{    int next;    int lenth;    int weight;//长度    int to;//终点} edge[20010];int n,cnt,head[10010],vis[10010],dp[10010];int ma(int a,int b){    return a>b?a:b;}void adde(int fa,int son,int w)//加边{    edge[cnt].to=son;    edge[cnt].next=head[fa];    edge[cnt].weight=w;    head[fa]=cnt++;}void dfs(int fa)//做一次dfs算出需要的数据{    vis[fa]=1;    int p=head[fa];    while(p!=-1)    {        if(vis[edge[p].to])        {            p=edge[p].next;            continue;        }        dfs(edge[p].to);        dp[fa]=ma(dp[fa],dp[edge[p].to]+edge[p].weight);        edge[p].lenth=dp[edge[p].to]+edge[p].weight;        p=edge[p].next;    }}void solve(int fa,int son){    if(vis[son])        return;    int maxx=0,p;    vis[son]=1;    p=head[fa];    while(p!=-1)//找到除了儿子节点以外权值最大的节点    {        if(edge[p].to!=son)           maxx=ma(maxx,edge[p].lenth);        p=edge[p].next;    }    p=head[son];    while(p!=-1)//更新一下儿子节点(假定当根节点)的权值    {        if(edge[p].to==fa)           {               edge[p].lenth=maxx+edge[p].weight;               break;           }        p=edge[p].next;    }    p=head[son];    while(p!=-1)//更新儿子节点的最长路径,同时继续搜寻儿子的儿子节点    {        dp[son]=ma(dp[son],edge[p].lenth);        solve(son,edge[p].to);        p=edge[p].next;    }}int main(){    int i,f,w,p;    while(~scanf("%d",&n))    {        memset(head,-1,sizeof head);        memset(dp,0,sizeof dp);        memset(vis,0,sizeof vis);        cnt=0;        for(i=2;i<=n;i++)        {            scanf("%d%d",&f,&w);            adde(f,i,w);            adde(i,f,w);        }        dfs(1);        memset(vis,0,sizeof vis);        p=head[1];        while(p!=-1)        {            solve(1,edge[p].to);            p=edge[p].next;        }        for(i=1;i<=n;i++)            printf("%d\n",dp[i]);    }    return 0;}