解题很好想,状态方程
dp[ u ][ j ]=max( dp[ u ][ j ] ,dp[ u ][ j - k ] + dp[ v ][ k ]);
此题还要建边,刚开始没想到建边,自己还写了个建边的以0为根,其实没必要,题目给的信息就够了。
状态方程很好想,就是背包是的范围弄错了,调了老大会。
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
using namespace std;
const int N=205;
int dp[N][N];
vector<int>V[N];
int val[N];
void init()
{
memset(dp,0,sizeof(dp));
for(int i=0;i<N;i++) V[i].clear();
}
void dfs(int u,int c)
{
int i;
dp[u][1]=val[u];//for(i=1;i<=c;i++) dp[u][i]=val[u];
for(i=0;i<(int)V[u].size();i++)
{
int v=V[u][i];
dfs(v,c-1);
for(int j=c;j>=1;j--)
for(int k=1;j-k>=1;k++)
dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);
// for(int j=c;j>=1;j--)
// printf("[%d] [%d] -->%d\n",u,j,dp[u][j]);
}
}
int main()
{
//freopen("Input.txt","r",stdin);
int n,m,i;
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0) break;
init();
int a,b;
for(i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
val[i]=b;
V[a].push_back(i);
}
dfs(0,m+1);
printf("%d\n",dp[0][m+1]);
}
}