http://acm.pku.edu.cn/JudgeOnline/problem?id=1155

Код:
#include <iostream>
#include <climits>
#include <list>
using namespace std;
const int BUFLEN = 10240;
int table[BUFLEN];
int M, N;

struct Edge
{
    int cost, dst;
    Edge(int d, int c)
        :dst(d), cost(c)
    {}
};


inline
bool fnIsUser(int number)
{
    static int tmp = N - M;
    return number >= tmp;
}

list<Edge> nodes[6000];
int moneys[6000];

int fnCount(int node, int bufbase)
{
    table[bufbase] = 0;
    if(fnIsUser(node))
    {
        table[bufbase + 1] = moneys[node - N + M];
        return 1;
    }
    else if(nodes[node].size())
    {
        int cntTotalChild = 0; 
        table[bufbase] = 0;
        for(list<Edge>::iterator it = nodes[node].begin(); it != nodes[node].end(); it++)  
        {
        int cntNewChild = fnCount(it->dst, bufbase + cntTotalChild + 1);  
            for(int i = 1; i <= cntNewChild; i++)
                table[bufbase + cntTotalChild + 1 + i] -= it->cost;
            for(int i = 0; i <= cntTotalChild + cntNewChild; i++)  
            {
                table[bufbase + cntTotalChild + cntNewChild + 2 + i] = INT_MIN;
                for(int j = max(i - cntNewChild, 0); j <= cntTotalChild && j <= i; j++)
                    table[bufbase + cntTotalChild + cntNewChild + 2 + i] = max(table[bufbase + j] + 
                    table[bufbase + cntTotalChild + 1 + i -j], table[bufbase + cntTotalChild + cntNewChild + 2 + i]);
            }
            for(int i = 0; i <= cntTotalChild + cntNewChild; i++)  
                table[bufbase + i] = table[bufbase + cntTotalChild + cntNewChild + 2 + i];
            cntTotalChild += cntNewChild; 
        }
        return cntTotalChild;
    }
    return 0;
}
int main()
{
    while(cin >> N >> M)
    {
        for(int i = 0; i < N - M; i++)
        {
            int numChild = 0;
            cin >> numChild;
            for(int j = 0; j < numChild; j++)
            {
                int cost, dst;
                cin >> dst >> cost;
                nodes[i].push_back(Edge(dst - 1, cost));
            }
        }
        for(int i = 0; i < M; i++)
            cin >> moneys[i];
        int ans = fnCount(0, 0);
        while(table[ans] < 0)   
            ans--;
        cout << ans << '\n';
    }
    return 0;
}