基础题,用前向星建图,开动态数组,感觉跟背包九讲里的分组背包有点相似。
ACcode:
#include<cstdio>
#include<cstring>
using namespace std;
const int nsize=220;
int n,m,r;
int b[nsize],v[nsize],dp[nsize];
int head[nsize],next[nsize],e[nsize],top;
void add(int p,int s,int pos)
{
next[pos]=head[p];
e[pos]=s;
head[p]=pos;
}
int Max(int a1,int a2)
{
return a1>a2?a1:a2;
}
void dfs(int rt)
{
v[rt]=0;
int tp[nsize];
memset(tp,0,sizeof(tp));
for (int i=head[rt];i!=-1;i=next[i])
{
if (v[e[i]])
{
dfs(e[i]);
for (int j=m;j>0;j--)
{
for (int k=0;k<=j;k++)
{
tp[j]=Max(tp[j],tp[k]+dp[j-k]);
}
}
}
}
for (int i=m+1;i>0;i--) dp[i]=tp[i-1]+b[rt];
}
int main()
{
while (~scanf("%d %d",&n,&m)&&(n+m))
{
top=dp[0]=b[0]=0;
memset(v,1,sizeof(v));
memset(head,-1,sizeof(head));
for (int i=1;i<=n;i++)
{
scanf("%d %d",&r,b+i);
add(r,i,top),top++;
}
dfs(0);
for (int i=1;i<=m+1;i++) dp[0]=Max(dp[0],dp[i]);
printf("%d\n",dp[0]);
}
return 0;
}