题意:

给定n个点,每个地点有value[i]的宝物,而且有的宝物必须是另一个宝物取了才能取,问取m个点可以获得的最多宝物价值

思路:

树形dp搞一下,0为根节点,m要+1,dfs从0开始跑一遍就好了

 

/* ***********************************************
Author        :devil
Created Time  :2016/3/23 19:23:54
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
#define N 210
int n,m,dp[N][N],v[N];
bool vis[N];
vector<int>eg[N];
void init()
{
    for(int i=0;i<=n;i++)
        eg[i].clear();
    memset(dp,0,sizeof(dp));
    memset(vis,false,sizeof(vis));
}
void dfs(int u)
{
    vis[u]=true;
    dp[u][1]=v[u];
    for(int i=0;i<eg[u].size();i++)
    {
        int to=eg[u][i];
        if(!vis[to]) dfs(to);
        for(int j=m;j>=1;j--)
            for(int k=1;k<j;k++)
                dp[u][j]=max(dp[u][j],dp[u][k]+dp[to][j-k]);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    int x,y;
    while(~scanf("%d%d",&n,&m)&&(n+m))
    {
        init();
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            v[i]=y;
            eg[x].push_back(i);
        }
        m++;
        dfs(0);
        printf("%d\n",dp[0][m]);
    }
    return 0;
}