Time Limit : 1000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 1   Accepted Submission(s) : 1

Font: Times New Roman | Verdana | Georgia

Font Size:  

Problem Description



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

Author

scnu

 

首先按所给信息建图,建立的是有向图。然后将1视为根节点第一遍dfs从叶往根递推,求出每个点所能到达的最远距离和次远距离,只有当这一个点有多条分支时才存在次远距离(注意这里是有方向);
该点所能到达的最远距离可能是第一遍dfs搜到最远距离,也有可能由父亲节点+父亲节点与该节点的距离所得。所以第二遍dfs从根节点1出发往树叶边遍历。
 
downf[i]表示以节点 i 向其 子树搜索 所能到达的最远距离
downs[i]表示次远距离
vis[i]记录 到达最远距离的那条边(最远 和次远 不会重边)
dp[i]表示 节点i 经其父亲节点延伸(延伸到父亲的最长或着次长),所能到达的最远距离
求 i的最远时, i可能在父亲的最长路径上,也可能不再,所以要记录
 
最远 可能是向上最远 也可能向下 所以最后要 max(downf[k],dp[k]);
 
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>

using namespace std;

const int N=10010;

struct node{
    int to,cap;
}a;

vector<node> vt[N];
int n,dp[N],downf[N],downs[N],vis[N];

void DFS1(int u){
    int flag1=-1,flag2=-1;
    if(downf[u])
        return ;
    int len=vt[u].size();
    if(len==0)
        return ;
    int MAX=-1;
    for(int i=0;i<len;i++){     //求最长距离,  由下往上递推 
        int v=vt[u][i].to;
        DFS1(v);                //先dfs
        if(MAX<downf[v]+vt[u][i].cap){  //后处理
            MAX=downf[v]+vt[u][i].cap;
            flag1=i;
        }
    }
    vis[u]=flag1;
    downf[u]=MAX;
    MAX=-1;
    for(int i=0;i<len;i++){     //求次长距离
        int v=vt[u][i].to;
        if(i!=flag1 && MAX<downf[v]+vt[u][i].cap){  //i!=flag1 保证最远距离和次远距离不会重边
            MAX=downf[v]+vt[u][i].cap;
            flag2=i;
        }
    }
    if(flag2!=-1)
        downs[u]=MAX;
}

void DFS2(int u){       //由上往下推 
    int len=vt[u].size();
    if(len==0)
        return ;
    for(int i=0;i<len;i++){
        int v=vt[u][i].to;
        if(i==vis[u])   //先处理
            dp[v]=max(downs[u],dp[u])+vt[u][i].cap;     //在父亲的最长路径上
        else
            dp[v]=max(downf[u],dp[u])+vt[u][i].cap;     //不在父亲的最长路径上
        DFS2(v);        //后dfs
    }
}

int main(){

    //freopen("input.txt","r",stdin);

    while(~scanf("%d",&n)){
        for(int i=0;i<=n;i++)
            vt[i].clear();
        int u;
        for(int v=2;v<=n;v++){
            scanf("%d%d",&u,&a.cap);
            a.to=v;
            vt[u].push_back(a);
        }
        memset(dp,0,sizeof(dp));
        memset(downf,0,sizeof(downf));
        memset(downs,0,sizeof(downs));
        DFS1(1);
        DFS2(1);
        for(int i=1;i<=n;i++)
            printf("%d\n",max(downf[i],dp[i]));
    }
    return 0;
}

 

 另一种建图:

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int VM=10010;

struct Edge{
    int to,nxt;
    int cap;
}edge[VM<<1];

int n,cnt,head[VM];
int dp[VM],downf[VM],downs[VM],vis[VM];

void addedge(int cu,int cv,int cw){
    edge[cnt].to=cv;    edge[cnt].cap=cw;   edge[cnt].nxt=head[cu];
    head[cu]=cnt++;
}

void DFS1(int u){
    int flag1=-1,flag2=-1;
    if(downf[u])
        return ;
    if(head[u]==-1)
        return ;
    int MAX=-1;
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        int v=edge[i].to;
        DFS1(v);
        if(MAX<downf[v]+edge[i].cap){
            MAX=downf[v]+edge[i].cap;
            flag1=i;
        }
    }
    vis[u]=flag1;
    downf[u]=MAX;
    MAX=-1;
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        int v=edge[i].to;
        if(i!=flag1 && MAX<downf[v]+edge[i].cap){
            MAX=downf[v]+edge[i].cap;
            flag2=i;
        }
    }
    if(flag2!=-1)
        downs[u]=MAX;
}

void DFS2(int u){
    if(head[u]==-1)
        return ;
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        int v=edge[i].to;
        if(i==vis[u])
            dp[v]=max(downs[u],dp[u])+edge[i].cap;
        else
            dp[v]=max(downf[u],dp[u])+edge[i].cap;
        DFS2(v);
    }
}

int main(){

    //freopen("input.txt","r",stdin);

    while(~scanf("%d",&n)){
        cnt=0;
        memset(head,-1,sizeof(head));
        int u,w;
        for(int v=2;v<=n;v++){
            scanf("%d%d",&u,&w);
            addedge(u,v,w);
        }
        memset(dp,0,sizeof(dp));
        memset(downf,0,sizeof(downf));
        memset(downs,0,sizeof(downs));
        DFS1(1);
        DFS2(1);
        for(int i=1;i<=n;i++)
            printf("%d\n",max(downf[i],dp[i]));
    }
    return 0;
}

 

相关文章: