两次树形dp,
第一次是求出
f(i)
以i为根的子树中的结点到i点的 最远距离和次远距离
第二次是求出
g(i)
以i为根的子树外的结点到i点的 最远距离
转移方程并不复杂哦~,最后 ans(i)=max(f(i),g(i))
#include<map>
#include<stack>
#include<queue>
#include<utility>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<iostream>
#include<algorithm>
#define Mp(x,y) std::make_pair(x,y)
#define Max1 first
#define Max2 second
const int MAXN = 10005;
int n;
struct Edge
{
int v,w,next;
Edge(int v = 0,int w = 0,int next = 0):v(v),w(w),next(next){};
}edge[MAXN<<1];
int el = 0, head[MAXN] = {0};
std::pair<int,int>f[MAXN];
int g[MAXN] = {0};
void NewEdge(int u,int v,int w){++el; edge[el] = Edge(v,w,head[u]); head[u] = el;}
namespace SonSolve
{
void DFS(int a,int fa)
{
for(int i = head[a]; i ; i = edge[i].next)
{
int p = edge[i].v;
if(p == fa) continue;
DFS(p , a);
int tmp = f[p].Max1 + edge[i].w;
if(tmp >= f[a].Max1)
f[a] = Mp(tmp,f[a].Max1);
else if(tmp > f[a].Max2)
f[a].Max2 = tmp;
else;
}
}
}
namespace FaSolve
{
void DFS(int a,int fa)
{
for(int i = head[a]; i ; i = edge[i].next)
{
int p = edge[i].v;
if(p == fa) continue;
int tmp = (f[p].Max1 + edge[i].w == f[a].Max1)?f[a].Max2:f[a].Max1;
g[p] = std::max(g[a], tmp) + edge[i].w;
DFS(p , a);
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("sgu149.in","r",stdin);
freopen("sgu149.out","w",stdout);
#endif
std::cin >> n;
for(int i = 2, to, len; i <= n; i++)
{
scanf("%d%d",&to,&len);
NewEdge(to,i,len);
NewEdge(i,to,len);
}
SonSolve::DFS(1,0);
FaSolve::DFS(1,0);
for(int i = 1; i <= n; i++)
printf("%d\n",std::max(f[i].Max1,g[i]));
fprintf(stderr,"%f",clock()*1.0/CLOCKS_PER_SEC);
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
}