悬关求调
查看原帖
悬关求调
353893
彭俊皓123楼主2023/10/20 08:55

写了半天感觉式子对了但是一直是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;
}
2023/10/20 08:55
加载中...