思路和常规的差不多,但有一点点不同,一遍dfs求出每个节点的子树中离它最远的长度和第二长的,第二遍dfs求出dp[x],dp[x]表示从x出发可以得到的最长的链
#include<bits/stdc++.h>
using namespace std;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-'){f=-1;}ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int N=100005;
int n;
int head[N],nex[N],to[N],val[N],idx,sonmax1[N],sonmax2[N],son1[N],son2[N],dp[N],dpson[N],maxn;
void add(int u,int v,int w){
nex[++idx]=head[u];
val[idx]=w;
to[idx]=v;
head[u]=idx;
return ;
}
void dfs(int x,int fa){
for(int i=head[x];i;i=nex[i]){
int y=to[i];
if(y==fa) continue;
dfs(y,x);
if(sonmax1[x]<=sonmax1[y]+val[i]){
sonmax2[x]=sonmax1[x];
son2[x]=son1[x];
sonmax1[x]=sonmax1[y]+val[i];
son1[x]=y;
}
else if(sonmax2[x]<sonmax1[y]+val[i]){
sonmax2[x]=sonmax1[y]+val[i];
son2[x]=y;
}
}
return ;
}
void dfs2(int x,int fa,int k){
if(dpson[fa]!=x&&x!=1){
dp[x]=dp[fa]+val[k];
if(sonmax1[x]>dp[x]){
dp[x]=sonmax1[x];
dpson[x]=son1[x];
}
else dpson[x]=fa;
}
else{
dp[x]=sonmax2[fa]+val[k];
dpson[x]=fa;
if(dp[x]<sonmax1[x]){
dp[x]=sonmax1[x];
dpson[x]=son1[x];
if(sonmax1[x]==sonmax2[x]){
dpson[x]=son2[x];
}
}
}
for(int i=head[x];i;i=nex[i]){
int y=to[i];
if(y==fa) continue;
dfs2(y,x,i);
}
return ;
}
int main(){
while(~scanf("%d",&n)){
idx=0;
memset(head,0,sizeof(head));
memset(dp,0,sizeof(dp));
memset(sonmax1,0,sizeof(sonmax1));
memset(sonmax2,0,sizeof(sonmax2));
for(int i=2;i<=n;i++){
int v=read(),w=read();
add(v,i,w);
}
dfs(1,0);
dfs2(1,0,0);
for(int i=1;i<=n;i++){printf("%d\n",dp[i]);}
}
return 0;
}
/*
5
1 2
2 1
3 1
1 1
*/