hdu 4267 树形DP

思路:先dfs一下,找出1,n间的路径长度和价值,回溯时将该路径长度和价值清零。那么对剩下的图就可以直接树形dp求解了。

#include<iostream>

#include<algorithm>

#include<cstring>

#include<cstdio>

#define inf 100000000

#define Maxn 110

using namespace std;

int vi[Maxn],head[Maxn],dp[Maxn][510],e,n,T,a[Maxn],len,sum;

struct Edge{

    int u,v,next,val;

}edge[Maxn*2];

void init()

{

    memset(vi,0,sizeof(vi));

    memset(head,-1,sizeof(head));

    memset(dp,0,sizeof(dp));

    memset(a,0,sizeof(a));

    e=len=sum=0;

}

void add(int u,int v,int val)

{

    edge[e].u=u,edge[e].v=v,edge[e].val=val,edge[e].next=head[u],head[u]=e++;

    edge[e].u=v,edge[e].v=u,edge[e].val=val,edge[e].next=head[v],head[v]=e++;

}

int dfs(int u)

{

    int i,v;

    vi[u]=1;

    if(u==1)

    {

        sum+=a[u];

        a[u]=0;

        return 1;

    }

    for(i=head[u];i!=-1;i=edge[i].next)

    {

        v=edge[i].v;

        if(vi[v]) continue;

        if(dfs(v))

        {

            len+=edge[i].val,edge[i].val=edge[i^1].val=0;

            sum+=a[u];

            a[u]=0;

            return 1;

        }

    }

    return 0;

}

void Treedp(int u)

{

    int i,v,j,k;

    vi[u]=1;

    for(i=head[u];i!=-1;i=edge[i].next)

    {

        v=edge[i].v;

        if(vi[v]) continue;

        Treedp(v);

        int cost=2*edge[i].val;

        for(j=T;j>=cost;j--){

            int temp=0;

            for(k=0;k<=j-cost;k++)

                temp=max(temp,dp[u][j-cost-k]+dp[v][k]);

                dp[u][j]=max(dp[u][j],temp);

        }



    }

    for(i=0;i<=T;i++)

        dp[u][i]+=a[u];

}

int main()

{

    int i,j,u,v,t;

    while(scanf("%d%d",&n,&T)!=EOF)

    {

        init();

        for(i=1;i<n;i++){

            scanf("%d%d%d",&u,&v,&t);

            add(u,v,t);

        }

        for(i=1;i<=n;i++)

            scanf("%d",a+i);

        dfs(n);

        if(len>T)

        {

            printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");

            continue;

        }

        T-=len;

        memset(vi,0,sizeof(vi));

        Treedp(n);

        printf("%d\n",dp[n][T]+sum);

    }

    return 0;

}

 

你可能感兴趣的:(HDU)