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;
}