求助树形背包
  • 板块学术版
  • 楼主zengwei
  • 当前回复1
  • 已保存回复1
  • 发布时间2020/11/22 16:20
  • 上次更新2023/11/5 07:31:29
查看原帖
求助树形背包
55886
zengwei楼主2020/11/22 16:20

为什么我会挂? 题目大意:以1号节点为根的树上每个点有代价p和价值v,要取某个点必须先取其父亲(1号除外),节点总数为n,价值和不超过m

#include<iostream>
#include<cstdio>
using namespace std;
typedef unsigned long long ull;
inline ull read(){
	ull x=0ll;bool f=true;char c=getchar();
	while(c>'9'||c<'0'){if(c=='-')f=false;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return f?x:-x;
}
struct node{
	int x,y,next;
}a[100001];int len,last[2001];
inline void ins(int x,int y){
	a[++len].x=x;a[len].y=y;
	a[len].next=last[x];last[x]=len;
}
int n,m,v[2001],p[2001],f[2001][2001],anss,ff[2001];
void dfs(int x,int fa){//f[x][i]以x为根的子树上花费i代价取得的最大价值 
	for(int i=p[x];i<=m;++i)f[x][i]=v[x];
	for(int k=last[x];k;k=a[k].next){
		int y=a[k].y;
		if(y==fa)continue;
		dfs(y,x);
		for(int i=m;i>=p[y]&&m-i>=p[x];i--){
			ff[i]=max(ff[i],f[y][i]+f[x][m-i]);
			if(i-1>=p[x])ff[i]=max(ff[i],ff[i-1]);
			if(i<m)ff[i+1]=max(ff[i+1],ff[i]);
		}
		for(int i=m;i>=p[y]&&m-i>=p[x];i--){
			f[x][i]=max(f[x][i],ff[i]);
			ff[i]=f[x][i];
		}
	}
}
int main(){
	n=read();m=read();
	for(int i=1;i<=n;i++){
		v[i]=read();p[i]=read();//v价值p代价 
	}
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		ins(u,v);ins(v,u);
	}
	dfs(1,0);
	for(int i=0;i<=m;i++)anss=max(anss,f[1][i]);
	printf("%d\n",anss);
	fclose(stdin);fclose(stdout);
}
2020/11/22 16:20
加载中...