题意:
n个点,n-1条边,每个边有权值。问这n个点到叶子节点的最大距离分别是多少。
题解:
建一个无向树,1为根结点。我们思考:一个树到叶子节点的最大距离,要么就是他子树中叶子节点到他的最大距离,要么就是找到一条不经过他的从他父亲节点过来的一条路径。那么,我们就这么思考,从他(称之为i)子树中的叶子节点到他的最大距离我们很容易能找到,如何去寻找从他父亲节点(称之为fa)过来的路径呢?一般来说,我们都是记录他父亲这个树中,父亲到其子树中叶子节点的最大距离,但是我们无法判断父亲路径经不经过他(i),所以我们对其父亲是从哪来的进行记录,并存一个次长距离,防止父亲的路径若是从他(i)来的,那么就判断父亲的次长路径和他(i)子树中的最长距离。这样,一个树型DP模型就出来了。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int list[10010],pos,n,dp[10010],a[10010],b[10010],it[10010];
struct P{
int u,v,w,next;
}point[30010];
void add(int fa,int son,int w){
point[pos].u=fa;
point[pos].v=son;
point[pos].w=w;
point[pos].next=list[fa];
list[fa]=pos++;
}
void dfs(int son,int fa){
int now=list[son];
while(now!=-1){
if(point[now].v==fa){
now=point[now].next;
continue;
}
dfs(point[now].v,son);
if(a[point[now].v]+point[now].w>a[son]){
it[son]=point[now].v;
}
a[son]=max(a[point[now].v]+point[now].w,a[son]);
now=point[now].next;
}
now=list[son];
while(now!=-1){
if(point[now].v==fa){
now=point[now].next;
continue;
}
int w=a[point[now].v]+point[now].w;
if(w>b[son]&&point[now].v!=it[son]){
b[son]=w;
}
now=point[now].next;
}
return;
}
void dfs1(int son,int fa){
int now=list[son];
while(now!=-1){
// printf("! son=%d fa=%d as=%d bs=%d ap=%d bp=%d\n",son,fa,a[son],b[son],a[point[now].v],b[point[now].v]);
// printf("! son=%d now=%d v=%d\n",son,now,point[now].v);
if(point[now].v==fa){
now=point[now].next;
continue;
}
if(it[son]==point[now].v){
if(b[son]+point[now].w>a[point[now].v]){
b[point[now].v]=a[point[now].v];
a[point[now].v]=b[son]+point[now].w;
it[point[now].v]=son;
}
else if(b[son]+point[now].w>b[point[now].v])b[point[now].v]=b[son]+point[now].w;
}
else{
if(a[son]+point[now].w>a[point[now].v]){
b[point[now].v]=a[point[now].v];
a[point[now].v]=a[son]+point[now].w;
it[point[now].v]=son;
}
else if(a[son]+point[now].w>b[point[now].v])b[point[now].v]=a[son]+point[now].w;
}
dfs1(point[now].v,son);
now=point[now].next;
}
return ;
}
int main(){
while(scanf("%d",&n)!=EOF){
pos=0;
memset(list,-1,sizeof(list));
for(int i=2;i<=n;i++){
int aa,bb;
scanf("%d%d",&aa,&bb);
add(i,aa,bb);
add(aa,i,bb);
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(dp,0,sizeof(dp));
dfs(1,0);
dfs1(1,0);
for(int i=1;i<=n;i++){
printf("%d\n",a[i]);
// printf("! a=%d b=%d it=%d\n",a[i],b[i],it[i]);
}
}
return 0;
}