写了半天感觉式子对了但是一直是10分,去看了眼题解发现式子没错,把题解 dfs 的部分替换过来就能过,但是看不出来自己写的 dfs 哪里错了......
代码里的 dfs1 是题解的,dfs2 是我自己的。
#include<iostream>
#include<vector>
#include<string.h>
#include<algorithm>
#define pii pair<int,int>
#define mp(x,y) make_pair(x,y)
#define f first
#define s second
using namespace std;
const int MAXN=3005,INF=0x3f3f3f3f;
int a,b,c;
int num[MAXN],fa[MAXN],siz[MAXN];
int dp[MAXN][MAXN],val[MAXN][MAXN];
vector<pii> edge[MAXN];
inline int read()
{
char x=getchar();int t=0;
while(!isdigit(x))x=getchar();
while(isdigit(x))t=(t<<3)+(t<<1)+(x^48),x=getchar();
return t;
}
bool cmp(pii x,pii y){return siz[x.f]>siz[y.f];}
int dfs1(int u){
if(u>a-b){
dp[u][1]=num[u];
dp[u][0]=0;
return 1;
}
dp[u][0]=0;
int leafs=0;
for(auto now:edge[u])
{
int v=now.f,w=now.s;
int t=dfs1(v);
leafs+=t;
for(int j=leafs;j>0;j--)
for(int k=0,kk=min(j,t);k<=kk;k++)
dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]-w);
}
return leafs;
}
void dfs2(int x)
{
dp[x][0]=0;
dp[x][1]=num[x];
siz[x]=(bool)num[x];
for(auto now:edge[x])
{
//if(now.f==fa[x])continue;
//fa[now.f]=x;
//for(int i=min(siz[now.f],y);i;--i)
dfs2(now.f);
siz[x]+=siz[now.f];
// for(int i=min(siz[now.f],y);i;--i)
for(int y=siz[x];y>=1;--y)
for(int i=0,kk=min(y,siz[now.f]);i<=kk;++i)
{
//cerr<<now.f<<endl;
dp[x][y]=max(dp[x][y],dp[x][y-i]+dp[now.f][i]-now.s);
//printf("dp[%d][%d]=%d + %d - %d->dp[%d][%d]=%d\n",now.f,i,dp[now.f][i],dp[x][y-i],now.s,x,y,dp[x][y]);
}
}
}
int main()
{
a=read();b=read();
for(int i=1;i<=a;++i)
for(int j=1;j<=a;++j)
dp[i][j]=-INF;
for(int i=1;i<=a-b;++i)
{
int k=read();
for(int j=1;j<=k;++j)
{
int x=read(),y=read();
edge[i].push_back(mp(x,y));
//edge[x].push_back(mp(i,y));
}
num[i]=0;
}
for(int i=a-b+1;i<=a;++i)num[i]=read();
//for(int i=1;i<=a;++i)dp[i][0]=0;
//dfs1(1);
dfs2(1);
//for(int i=a;i>=1;--i)dfs2(1,i);
int ans=0;
// for(int i=1;i<=a;++i)
// {
// ans=max(ans,val[1][i]);
// printf("%d:",i);
// for(int j=1;j<=siz[i];++j)
// printf("%d ",dp[i][j]);
// puts("");
// }
for(int i=b;i>=0;--i)
if(dp[1][i]>=0){ans=i;break;}
printf("%d\n",ans);
//for(int i=1;i<=a;++i)printf("(%d,%d):%d\n",dp[i][0],dp[i][1],val[i]);
return 0;
}