hdu 2196 树形dp

/*先走一遍dfs找到每个点到他的子节点的位置,回溯的时候找到最大值和次大值
再用一个dfs来更新值,先看是否是u最长路上的点,如果是的话用最大值+权值更新最大值和次大值,否则的话用次大值+权值更新最大值和次大值
*/
#include<stdio.h>
#include<string.h>
#define N  11000
struct node
{
    int u,v,w,next;
} bian[N*2];
int ma[N*2],ma2[N*2];
int n,yong,visit[N],head[N];
void addedge(int u,int v,int w)
{
    bian[yong].u=u;
    bian[yong].v=v;
    bian[yong].w=w;
    bian[yong].next=head[u];
    head[u]=yong++;
}
int dfs(int u)
{
    visit[u]=1;
    int max1=0,max2=0,i,f;
    for(i=head[u]; i!=-1; i=bian[i].next)
    {
        int v=bian[i].v;
        if(!visit[v])
        {
            f=dfs(v)+bian[i].w;
            if(max1<f)
            {
                max2=max1;
                max1=f;
            }
            else if(max2<f)
                max2=f;
        }
    }
    ma[u]=max1;//找到最大值和次大值
    ma2[u]=max2;
    return max1;
}
int MAX(int a,int b)
{
    return a>b?a:b;
}
void dfs1(int u)
{
    int i;
    visit[u]=1;
    for(i=head[u]; i!=-1; i=bian[i].next)
    {
        int v=bian[i].v;
        if(visit[v])continue;
        if(bian[i].w+ma[v]!=ma[u])//如果没有在最长边上
        {
            if(ma[v]<ma[u]+bian[i].w)//和v到子节点比较更新最大值
            {
                ma2[v]=ma[v];
                ma[v]=ma[u]+bian[i].w;
            }
            else 
                if(ma2[v]<ma[u]+bian[i].w)//刚开始没有考虑还需要实时更新次大值
                ma2[v]=ma[u]+bian[i].w;

        }
        else
        {
            if(ma[v]<ma2[u]+bian[i].w)//在最长边上
            {
                ma2[v]=ma[v];
                ma[v]=ma2[u]+bian[i].w;
            }
            else if(ma2[v]<ma2[u]+bian[i].w)
                ma2[v]=ma2[u]+bian[i].w;
        }
        dfs1(v);
    }
    return ;
}
int main()
{
    int i,a,b;
    while(scanf("%d",&n)!=EOF)
    {
        yong=0;
        memset(head,-1,sizeof(head));
        for(i=2; i<=n; i++)
        {
            scanf("%d%d",&a,&b);
            addedge(i,a,b);
            addedge(a,i,b);
        }
        memset(ma,0,sizeof(ma));
        memset(ma2,0,sizeof(ma2));
        memset(visit,0,sizeof(visit));
        dfs(1);
        memset(visit,0,sizeof(visit));
        dfs1(1);
        for(i=1; i<=n; i++)
            printf("%d
",ma[i]);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410675.html