//要得到一个点的能够传递信息的最远距离,无非就是比较他父亲节点延伸的最远距离和这个点的子树的最远距离,最较大值即可。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#define MAXN 10010
using namespace std;
int n,tot;
int head[MAXN],dis1[MAXN],dis2[MAXN],vismax[MAXN],dp[MAXN];
//dis1[i]指i子树里i到一个叶子节点的的最长路,dis2[i]指i子树里i到叶子节点的一个次长路,dp[i]表示 节点i 经其父亲节点延伸,所能到达的最远距离
struct edge{
int to;
int next;
int l;
}edge[MAXN];
void init(){
tot=0;
for(int i=0;i<=n;i++)
head[i]=-1;
}
void add_edge(int a,int b,int c){
edge[tot].to=b;
edge[tot].l=c;
edge[tot].next=head[a];
head[a]=tot++;
}
void dfs(int s){
int k;
for(int i=head[s];i!=-1;i=edge[i].next){
int To=edge[i].to;
int w=edge[i].l;
//puts("1");
dfs(To);
if(dis1[s]<w+dis1[To]){
dis1[s]=w+dis1[To];
k=To;
}
}
vismax[s]=k;
for(int i=head[s];i!=-1;i=edge[i].next){
int To=edge[i].to;
int w=edge[i].l;
if(vismax[s]!=To && dis2[s]<w+dis1[To]){
dis2[s]=w+dis1[To];
}
}
}
void dfs1(int s){
for(int i=head[s];i!=-1;i=edge[i].next){
int To=edge[i].to;
int w=edge[i].l;
if(vismax[s]==To)
dp[To]=max(dp[s],dis2[s])+w;
else
dp[To]=max(dp[s],dis1[s])+w;
dfs1(To);
}
}
int main(){
int i,v,l;
while(~scanf("%d",&n)){
init();
for(i=2;i<=n;i++){
scanf("%d%d",&v,&l);
add_edge(v,i,l);
//add_edge(i,v,l);
}
memset(dp,0,sizeof dp);
memset(vismax,0,sizeof vismax);
memset(dis1,0,sizeof dis1);
memset(dis2,0,sizeof dis2);
dfs(1);
dfs1(1);
for(i=1;i<=n;i++){
dp[i]=max(dp[i],dis1[i]);
printf("%d\n",dp[i]);
}
}
return 0;
}
/*
9
1 1
2 1
3 1
1 1
5 1
6 1
7 1
8 1
*/
hdu Computer
最新推荐文章于 2021-08-04 10:25:29 发布