求助!树D01背包惨剩10分TAT
查看原帖
求助!树D01背包惨剩10分TAT
386890
Kogenta楼主2023/11/4 13:09

不T不M无玄学,但是WA声一片,球球汁源TAT
以下代码(含注释):

#include<bits/stdc++.h>
using namespace std;
const int maxn=3e3+5;
struct edge{
	int val;
	int to;
}fa[2*maxn];
int con[maxn];
int dp[maxn][maxn];//from node x select y (son) nodes with least cost or most earning.
vector<int>v[maxn];
int sz[maxn];
void conn(int a,int b,int w){//building tree (single_direction edge & father relation)
	fa[b].val=w;
	fa[b].to=a;
	v[a].push_back(b);
	return ;
}
int n,m;
void dfs(int x){//calculate leaves in sz[x]
	if(x>n-m)sz[x]=1;
	else sz[x]=0;
	for(int i=0;i<v[x].size();i++){
		int now=v[x][i];
		dfs(now);
		sz[x]+=sz[now];
	}
	return ;
}
int acum[maxn];//temporarily recording number of leaves before
void deal(int x){
	//printf("Now scanning node %d (father node: %d)\n",x,fa[x].to);
	int fa_=fa[x].to;
	for(int i=sz[x];i>=1;i--){
		for(int j=acum[fa_];j>=0;j--){
			int neww=dp[fa_][j]+dp[x][i]-fa[x].val;
			if(neww>dp[fa_][i+j]){
				dp[fa_][i+j]=neww;
				//printf("node %d's leaves %d data now updated to %d. (Choosing %d nodes from %d, costing %d to pass)\n",fa_,j+i,dp[fa_][j+i],i,x,fa[x].val);
			}
		}
	}
	acum[fa_]+=sz[x];
	con[fa_]--;
	if(con[fa_]==0 && fa_!=1)deal(fa_);
	return ;
}
int main(){
//	freopen("test1.txt","r",stdin);
//	freopen("testout.txt","w",stdout);
	int cnt=0;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n-m;i++){
		scanf("%d",&con[i]);
		for(int j=1;j<=con[i];j++){
			cnt++;
			int t,w;
			scanf("%d %d",&t,&w);
			conn(i,t,w);
		}
	}
	for(int i=1;i<=n;i++){
		if(i<=n-m){
			for(int j=1;j<=m;j++){
				dp[i][j]=-2e9;
			}
		}
		else{
			scanf("%d",&dp[i][1]);
		}
	}
	dfs(1);
	for(int i=n-m+1;i<=n;i++){
		deal(i);
	}
	for(int i=m;i>=0;i--){
		if(dp[1][i]>=0){
			printf("%d",i);
			break;
		}
	}
	return 0;
}
2023/11/4 13:09
加载中...