【树形DP】HDU 1561 The more, The Better

通道:http://acm.hdu.edu.cn/showproblem.php?pid=1561

题意:有依赖关系的点权森林,求选m个点权和最大。

思路:dp[i][j]:i子树选j个节点,dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[son[i]][k]),森林的处理就是增加一个点即可。

代码:

#include<stdio.h>
#include<string.h>
#define N 205
int n,m,edgeNum=0;
int ans[N],dp[N][N];
int visit[N],head[N];
struct Line{int v,next;}edge[N];
int max(int a,int b){return a>b?a:b;}
void add(int u,int v)
{
    edge[edgeNum].v=v;
    edge[edgeNum].next=head[u];
    head[u]=edgeNum++;
}
void dfs(int root)
{
    visit[root]=1;
    for(int i=head[root];i!=-1;i=edge[i].next) {
        int u=edge[i].v;
        if(!visit[u]) {
            dfs(u);
            for(int k=m;k>=0;k--)
              for(int j=0;j<=k;j++)
              dp[root][k+1]=max(dp[root][k+1],dp[root][k-j+1]+dp[u][j]);
        }
    }
}
int main() {
    int a,b;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0) break;
        edgeNum=ans[0]=0;
        memset(dp,0,sizeof(dp));
        memset(head,-1,sizeof(head));
        memset(visit,0,sizeof(visit));
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&a,&b);
            ans[i]=b;
            add(a,i); dp[i][1] = b;
        }
        dfs(0);
        printf("%d\n",dp[0][m+1]);
    }
}
View Code

 

posted @ 2014-11-03 19:38  mithrilhan  阅读(169)  评论(0编辑  收藏  举报