原题链接
请直接看code
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct edge
{
int to;
int val;
};
vector<edge> G[3005];
int son[3005]={0};
int dp[3005][3005]={0};
void ss(int now)
{
if(now>=n-m+1&&now<=n) return;
for(int i=0;i<G[now].size();i++)
{
int next=G[now][i].to;
ss(next);
son[now]+=son[next];
}
for(int j=1;j<=son[now];j++)dp[now][j]=-1e9;
for(int i=0;i<G[now].size();i++)//i代表节点now的第(i+1)个子节点
{
int next=G[now][i].to,cost=G[now][i].val;//分别代表子节点下标,边权值
for(int j=son[now];j>=1;j--)//j代表当前节点now待计算的是叶子恰好j个时,消耗的费用
{
int left=min(j,son[next]);//代表当前子节点最多能取left个叶子
for(int l=left;l>=1;l--)
{
if(dp[now][j-l]==-1e9)continue;//说明目前从当前叶子节点取l个叶子达不到总叶子为j个的要求
dp[now][j]=max(dp[now][j],dp[now][j-l]+dp[next][l]-cost);
}
}
}
}
int main()
{
cin>>n>>m;
int p=n-m;
for(int i=1;i<=n-m;i++)
{
int k;
cin>>k;
while(k--)
{
int x,v;
cin>>x>>v;
G[i].push_back({x,v});
}
}
for(int i=n-m+1;i<=n;i++)
{
cin>>dp[i][1];
son[i]=1;
}
ss(1);//代表深搜?作用是计算以当前节点为根节点的树所有取叶子的情况
for(int i=son[1];i>=0;i--)
if(dp[1][i]>=0)//这道题有点奇怪,dp中的值并不是答案,而是对答案的限制
{
cout<<i;
return 0;
}
return 0;
}