基本题吧 错了好几次 G[0]没清空 从1开始清空了 伤不起 其他没什么难度
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <vector>
#include <cstdlib>
using namespace std;
const int maxn = 210;
vector <int> G[maxn];
int dp[maxn][maxn];
int a[maxn];
int sum[maxn];
int cnt;
map <string, int> id;
int n, m;
int in[maxn];
int ID(string s)
{
if(id[s])
return id[s];
id[s] = cnt++;
return id[s];
}
void init()
{
cnt = 1;
id.clear();
a[0] = 999999999;
for(int i = 0; i <= n; i++)
{
G[i].clear();
a[i] = 999999999;
in[i] = 0;
}
}
void dfs(int u)
{
sum[u] = 1;
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
dfs(v);
sum[u] += sum[v];
}
for(int i = 1; i <= n; i++)
{
dp[u][i] = 999999999;
}
dp[u][0] = 0;
//printf("%d\n", dp[u][sum[u]]);
dp[u][sum[u]] = a[u];
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
for(int j = sum[u]; j >= 0; j--)
{
for(int k = 1; k <= sum[v]; k++)
{
if(j < k)
break;
dp[u][j] = min(dp[u][j], dp[u][j-k] + dp[v][k]);
}
}
}
//
}
int main()
{
char str[1000];
while(gets(str) && str[0] != '#')
{
sscanf(str, "%d %d", &n, &m);
init();
for(int i = 1; i <= n; i++)
{
gets(str);
char *p = strtok(str, " ");
int flag = 0;
int u, v, w;
while(p)
{
if(!flag)
{
u = ID(p);
//G[0].push_back(u);
}
else if(flag == 1)
{
w = atoi(p);
a[u] = w;
}
else
{
v = ID(p);
G[u].push_back(v);
in[v]++;
}
p = strtok(NULL, " ");
flag++;
}
}
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; i++)
if(!in[i])
G[0].push_back(i);
dfs(0);
int ans = 999999999;
for(int i = m; i <= n; i++)
ans = min(ans, dp[0][i]);
printf("%d\n", ans);
}
return 0;
}