题意:
一棵树,对于其中的每个点,求与这个点距离最远的点的距离。
解法:
两次DFS。
第一次DFS时求出每个点的子树中的最远距离和次远距离(从下向上进行更新)。
第二次DFS时求出每个点的最远距离(从上向下进行更新;仔细分析就可以知道,一个点的最远距离只可能是由它的子树得到,或者从它的父结点的最长距离或者次长距离加上它与父节点的距离得到。)
#define debug
#define file
double abcxx00;
#define FF cout<<"==================================input:", cin>>abcxx00;
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<sstream>
#include<string>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<vector>
#include<queue>
#include<stack>
#include<list>
#include<set>
#include<map>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
const int maxn = 1e5 +5;
int n;
typedef pair<int,int> pii;
vector<pii>adj[maxn];
int disDown[maxn][2]; /// 0 for longest!!
void dfs1(int a, int fax){
disDown[a][0] = disDown[a][1] = 0;
int s,f,b;
for(s=adj[a].size(),f=0; f < s; f++){
b = adj[a].at(f).fi;
if(b != fax){
dfs1(b, a);
int t = disDown[b][0]+adj[a].at(f).se;
if(t >= disDown[a][0]){
disDown[a][1] = disDown[a][0];
disDown[a][0] = t;
}
else if(t > disDown[a][1]){
disDown[a][1] = t;
}
}
}
// printf("id:%d %d %d\n", a,disDown[a][0],disDown[a][1]);
}
void dfs2(int a, int fax){
int s,f,b,lenn,t;
for(s=adj[a].size(),f=0; f < s; f++){
b = adj[a].at(f).fi;
lenn = adj[a].at(f).se;
if(b != fax){
if(disDown[b][0]+lenn == disDown[a][0]){
t = disDown[a][1]+lenn;
}
else{
t = disDown[a][0]+lenn;
}
if(t >= disDown[b][0]){
disDown[b][1] = disDown[b][0];
disDown[b][0] = t;
}
else if(t > disDown[b][1]){
disDown[b][1] = t;
}
dfs2(b, a);
}
}
// printf("id:%d %d\n", a,disDown[a][0]);
}
void cyh(){
dfs1(1, -1);
dfs2(1, -1);
for(int e=1; e <= n; e++){
printf("%d\n", disDown[e][0]);
}
}
int main(){
int e,x,len;
while(cin >> n){
for(e=1; e <= n; e++){
adj[e].clear();
}
for(e=2; e <= n; e++){
scanf("%d %d", &x,&len);
adj[e].pb(mp(x,len));
adj[x].pb(mp(e,len));
}
cyh();
}
return 0;
}