给出一个森林,每棵树均为一组物品,首先推出每棵树可以组成的物品种类。
然后是基本的分组背包模板。
即 最外层枚举组数,次外层枚举背包容量,内层枚举物品体积。
对于每棵树有 ans[root][i+j] = ans[root][ i ] + ans[son][ j ]。
题水数据也水,不多说了。
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long int
#define _LL __int64
#define _INF 0x3f3f3f3f
#define Mod 1000000007
#define LM(a,b) (((ULL)(a))<<(b))
#define RM(a,b) (((ULL)(a))>>(b))
using namespace std;
const int MAXN = 210;
struct N
{
int u,v,w,next;
} edge[MAXN*2];
int head[MAXN];
int Top;
void Link(int u,int v,int w = -1)
{
edge[Top].u = u;
edge[Top].v = v;
edge[Top].w = w;
edge[Top].next = head[u];
head[u] = Top++;
}
void Init_head_Top(int n)
{
memset(head,-1,sizeof(int)*(n+2));
Top = 0;
}
int dp[MAXN];
int ans[MAXN][MAXN];
int root[MAXN];
int Top_Root;
int price[MAXN];
void dfs(int s,int m)
{
ans[s][1] = price[s];
for(int p = head[s] ; p != -1; p = edge[p].next)
{
dfs(edge[p].v,m);
for(int i = m;i >= 0; --i)
{
for(int j = m-i;j >= 1; --j)
{
if(ans[s][i] != -1 && ans[s][i+j] < ans[s][i] + ans[edge[p].v][j])
ans[s][i+j] = ans[s][i] + ans[edge[p].v][j];
}
}
}
}
int main()
{
int n,m;
int i,j,k,v;
while(scanf("%d %d",&n,&m) && (n||m))
{
Init_head_Top(n);
Top_Root = 0;
memset(dp,-1,sizeof(dp));
memset(ans,-1,sizeof(ans));
for(i = 1; i <= n; ++i)
{
scanf("%d %d",&v,&price[i]);
if(v)
Link(v,i);
else
root[Top_Root++] = i;
}
for(i = 0; i < Top_Root; ++i)
{
dfs(root[i],m);
}
dp[0] = 0;
for(j = 0; j < Top_Root; ++j)
{
for(i = m;i >= 0; --i)
{
if(dp[i] != -1)
{
for(k = m-i;k >= 1; --k)
{
if(ans[root[j]][k] != -1 && dp[i] != -1 && dp[i+k] < dp[i] + ans[root[j]][k])
dp[i+k] = dp[i] + ans[root[j]][k];
}
}
}
}
// for(i = 1; i <= m; ++i)
// {
// // printf("cost = %2d w = %2d\n",i,dp[i]);
// }
//
// for(i = 1; i <= n; ++i)
// {
// for(j = 1; j <= m; ++j)
// {
// //printf("%2d ",ans[i][j]);
//
// }
// // puts("");
// }
int Max = dp[1];
for(i = 1; i <= m ; ++i)
Max = max(Max,dp[i]);
printf("%d\n",Max);
}
return 0;
}