/*先走一遍dfs找到每个点到他的子节点的位置,回溯的时候找到最大值和次大值
再用一个dfs来更新值,先看是否是u最长路上的点,如果是的话用最大值+权值更新最大值和次大值,否则的话用次大值+权值更新最大值和次大值
*/
#include<stdio.h>
#include<string.h>
#define N 11000
struct node
{
int u,v,w,next;
} bian[N*2];
int ma[N*2],ma2[N*2];
int n,yong,visit[N],head[N];
void addedge(int u,int v,int w)
{
bian[yong].u=u;
bian[yong].v=v;
bian[yong].w=w;
bian[yong].next=head[u];
head[u]=yong++;
}
int dfs(int u)
{
visit[u]=1;
int max1=0,max2=0,i,f;
for(i=head[u]; i!=-1; i=bian[i].next)
{
int v=bian[i].v;
if(!visit[v])
{
f=dfs(v)+bian[i].w;
if(max1<f)
{
max2=max1;
max1=f;
}
else if(max2<f)
max2=f;
}
}
ma[u]=max1;//找到最大值和次大值
ma2[u]=max2;
return max1;
}
int MAX(int a,int b)
{
return a>b?a:b;
}
void dfs1(int u)
{
int i;
visit[u]=1;
for(i=head[u]; i!=-1; i=bian[i].next)
{
int v=bian[i].v;
if(visit[v])continue;
if(bian[i].w+ma[v]!=ma[u])//如果没有在最长边上
{
if(ma[v]<ma[u]+bian[i].w)//和v到子节点比较更新最大值
{
ma2[v]=ma[v];
ma[v]=ma[u]+bian[i].w;
}
else
if(ma2[v]<ma[u]+bian[i].w)//刚开始没有考虑还需要实时更新次大值
ma2[v]=ma[u]+bian[i].w;
}
else
{
if(ma[v]<ma2[u]+bian[i].w)//在最长边上
{
ma2[v]=ma[v];
ma[v]=ma2[u]+bian[i].w;
}
else if(ma2[v]<ma2[u]+bian[i].w)
ma2[v]=ma2[u]+bian[i].w;
}
dfs1(v);
}
return ;
}
int main()
{
int i,a,b;
while(scanf("%d",&n)!=EOF)
{
yong=0;
memset(head,-1,sizeof(head));
for(i=2; i<=n; i++)
{
scanf("%d%d",&a,&b);
addedge(i,a,b);
addedge(a,i,b);
}
memset(ma,0,sizeof(ma));
memset(ma2,0,sizeof(ma2));
memset(visit,0,sizeof(visit));
dfs(1);
memset(visit,0,sizeof(visit));
dfs1(1);
for(i=1; i<=n; i++)
printf("%d\n",ma[i]);
}
return 0;
}