hdu 1561 The more, The Better 树形背包

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561

题意:给出n个城堡,每个城堡里有若干宝物。有些城堡攻占之前要先攻占另一座城堡。求攻占m座城堡的最大宝物。


给出的输入可以看出,每个城堡都有一个或零个父亲节点。也就是这些城堡组成了森林。我们可以设置一个0号城堡,作为每一个没有父亲节点的父亲。这样就简化成我们熟悉的树形背包问题。0号城堡的宝物数为0。由于我们人为增加了一个城堡,而且攻占任何城堡之前都要攻占它,所以我们需要求出攻占m+1座城堡的最大宝物数。

接下来就是一个树形背包的模板。

#include <iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#define N 220
using namespace std;

vector<int>r[N];
int w[N],n,m,d[N][N];

void dfs(int t)
{
    for(int i=1;i<=m;i++)   d[t][i]=w[t];
    for(int i=0;i<r[t].size();i++)
    {
        int c=r[t][i];
        dfs(c);
        for(int j=m;j>=1;j--)
            for(int k=1;k<j;k++)
                d[t][j]=max(d[t][j],d[t][j-k]+d[c][k]);
    }
}

int main()
{
    while(~scanf("%d%d",&n,&m)&&(n||m))
    {
        for(int i=0;i<=n;i++)   r[i].clear();
        for(int i=1;i<=n;i++)
        {
            int u;
            scanf("%d%d",&u,&w[i]);
            r[u].push_back(i);
        }
        w[0]=0;
        m++;
        memset(d,0,sizeof(d));
        dfs(0);
        cout<<d[0][m]<<endl;
    }
}


你可能感兴趣的:(动态规划,ACM,HDU,树状DP,树形背包)