题意: N 个点 N-1条边 每条边有权值 求每个点所能达的最长距离
// 树形dp 2次dfs 一次转成有根树、并求出每个子树(以i为根)到叶子节点的最大距离 还有就是从与i相连的个子节点j遍历下去的最大距离
// 其实 每个子树(以i为根)到叶子节点的最大距离 就是 max(child[i][j]);
#include <iostream>
#include <algorithm>
#include <queue>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
#define MOD 1000000007
#define maxn 10010
vector<__int64> E[maxn],V[maxn],child[maxn];// E[i][id] 表示 i连出的节点 E[i][id] V[i][id]是对应的边权值 child[i][id]为以各个子节点遍历的各个最大值
__int64 ans[maxn],from[maxn],father[maxn];// ans[i]表示以i为根的树 i到叶子的最大值 ans[i]=max(child[i][id]) id=0,1,..len-1.
// from[i] 表示ans[i]是由哪个点得到的 father[i]表示 i到除去以i为根的树之外的点的最大值就是从父节点那里可以到达i来的最大值
int n;
__int64 dfs1(int u){
int i,v,id;
__int64 tp,rt=-1;
int len=E[u].size();
if(!len) return 0;
for(i=0;i<len;i++){
v=E[u][i];
tp=dfs1(v);
tp+=V[u][i];
// printf("tp= %I64d
",tp);
child[u].push_back(tp);
if(tp>rt){
rt=tp;
id=v;
}
}
from[u]=id;
return ans[u]=rt;
}
void dfs2(int u){
int i,v;
__int64 tp;
int len=E[u].size();
if(!len) return;
for(i=0;i<len;i++){
v=E[u][i];
tp=0;//忘记把 tp放进来初始化了、白白WA了次
if(from[u]!=v){
tp=ans[u]+V[u][i];
if(tp>ans[v]){
ans[v]=tp;
from[v]=u;
}
father[v]=tp;
}
else{
for(int j=0;j<len;j++)
if(j!=i)
tp=max(tp,child[u][j]);
// printf("u=%d %I64d
",u,tp);
father[v]=max(father[u],tp)+V[u][i];
tp=max(father[u]+V[u][i],tp+V[u][i]);
if(tp>ans[v]){
ans[v]=tp;
from[v]=u;
}
}
dfs2(v);
}
}
int main()
{
int i,k;
int val;
while(scanf("%d",&n)!=EOF){
for(i=1;i<=n;i++){
E[i].clear();
V[i].clear();
child[i].clear();
ans[i]=0;
from[i]=i;
}
father[1]=0;
for(i=2;i<=n;i++)
{
scanf("%d %d",&k,&val);
E[k].push_back(i);
V[k].push_back(val);
}
dfs1(1);
//printf("ddd=");
dfs2(1);
// printf("%I64d ",child[2][1]);
for(i=1;i<=n;i++) printf("%I64d
",ans[i]);
//printf("%I64d
",ans[i]);
}
return 0;
}