这题自己没想出来,,连续做了几天的树形DP结果反而思路被限制了,现在想来这题其实不难= =!主要是既要存 i 到叶子的最大值以及取得这个最大值的关联儿子节点,还要存取得次大的值这些信息。因为最后扩展到全部节点的时候可能出现 j 的父亲节点 i 恰好是 i 取得max的关联儿子节点,这样状态就无法转移了,于是我们就需要一个次大值的信息来解决这种问题。(最大与次大严格不重复)接下来就很简单了
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int head[10050];
struct NODE
{
int to,len,next;
}edge[20000];
int N;
int imax[10050],imax2[10050];
int id[10050],id2[10050];
void dfs1(int x)
{
imax[x]=imax2[x]=0;
int i,to;
for(i=head[x];i!=-1;i=edge[i].next)
{
to=edge[i].to;
dfs1(to);
if(imax2[x] < imax[to] + edge[i].len)
{
imax2[x]=imax[to] + edge[i].len;
id2[x]=to;
if(imax[x] < imax2[x])
{
swap(imax[x],imax2[x]);
swap(id[x],id2[x]);
}
}
}
}
void dfs2(int x)
{
int i,to;
for(i=head[x];i!=-1;i=edge[i].next)
{
to=edge[i].to;
if(to == id[x])
{
if(edge[i].len + imax2[x] > imax2[to])
{
imax2[to]=edge[i].len+imax2[x];
id2[to]=x;
if(imax2[to] > imax[to])
{
swap(imax2[to],imax[to]);
swap(id[to],id2[to]);
}
}
}
else
{
if(edge[i].len + imax[x] > imax2[to])
{
imax2[to]=edge[i].len+imax[x];
id2[to]=x;
if(imax2[to] > imax[to])
{
swap(imax2[to],imax[to]);
swap(id[to],id2[to]);
}
}
}
dfs2(to);
}
}
int main()
{
while(~scanf("%d",&N))
{
int i,j,len;
int c;
memset(head,-1,sizeof(head));
for(i=2,c=0;i<=N;i++)
{
scanf("%d %d",&j,&len);
edge[c].to=i,edge[c].len=len,edge[c].next=head[j],head[j]=c++;
}
dfs1(1);
dfs2(1);
for(i=1;i<=N;i++) printf("%d\n",imax[i]);
}
}