HDU 4267

来源:互联网 发布:王者荣耀类似源码 编辑:程序博客网 时间:2024/04/28 04:43

简单树形DP

#include<cstdio>#include<cstring>#include<algorithm>#define N 102using namespace std;struct Edge{    int v,w,next;}edge[N*2];int n,t;int head[N],cnt;int pre[N],cost[N],num[N];bool mark[N];int dp[N][502],yes[N];int dpdp[N][502],allnum;void addedge(int u,int v,int w){    edge[cnt].v=v;    edge[cnt].w=w;    edge[cnt].next=head[u];    head[u]=cnt++;    edge[cnt].v=u;    edge[cnt].w=w;    edge[cnt].next=head[v];    head[v]=cnt++;}void init(){    memset(head,-1,sizeof(head));    memset(pre,-1,sizeof(pre));    memset(cost,0,sizeof(cost));    memset(mark,0,sizeof(mark));    memset(dp,-1,sizeof(dp));    cnt=0;    memset(dpdp,-1,sizeof(dpdp));    dpdp[0][0]=0;    allnum=0;}void dfs(int u,int father){    int i;    for(i=head[u];i!=-1;i=edge[i].next){        int v=edge[i].v;        int w=edge[i].w;        if(v==father)continue;        pre[v]=u;        cost[v]=w+cost[u];        dfs(v,u);    }}void DP(int u,int father){    int i,j,sum=0,p;    for(i=head[u];i!=-1;i=edge[i].next){        int v=edge[i].v;        if(v==father || mark[v])continue;        sum++;        DP(v,u);    }    dp[u][0]=num[u];    if(sum==0)        return ;    for(i=head[u];i!=-1;i=edge[i].next){        int v=edge[i].v;        int w=edge[i].w;        if(v==father || mark[v])continue;        for(j=t;j>=w*2;j--){            for(p=w*2;p<=j;p++)                if(dp[u][j-p]!=-1 && dp[v][p-w*2]!=-1)                    dp[u][j]=max(dp[u][j],dp[u][j-p]+dp[v][p-w*2]);        }    }}int main(){    int u,v,w;    int i,j,p;    while(scanf("%d %d",&n,&t)==2){        init();        for(i=1;i<n;i++){            scanf("%d %d %d",&u,&v,&w);            addedge(u,v,w);        }        dfs(1,0);        for(i=1;i<=n;i++)            scanf("%d",&num[i]);    //一定要在下句之前读入,否则进入if之后就有可能continue;        if(t<cost[n]){            printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");            continue;        }        int tem=n;        while(tem!=-1){            mark[tem]=1;            tem=pre[tem];        }        t-=cost[n];        for(i=1;i<=n;i++){            if(mark[i]==0)continue;            yes[++allnum]=i;            DP(i,0);        }        int ans=0;        for(i=1;i<=allnum;i++){            for(j=t;j>=0;j--)                for(p=0;p<=j;p++)                    if (dp[yes[i]][p] != -1 && dpdp[i-1][j-p]!=-1)                        dpdp[i][j]=max(dpdp[i][j],dpdp[i-1][j-p]+dp[yes[i]][p]);        }        for (int i = 0; i <= t; i++)            ans = max(ans, dpdp[allnum][i]);        printf("%d\n",ans);    }    return 0;}



原创粉丝点击