社区讨论

第一次写树上背包,问个小问题

P2014[CTSC1997] 选课参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@lo7lwo5u
此快照首次捕获于
2023/10/27 03:58
2 年前
此快照最后确认于
2023/10/27 03:58
2 年前
查看原帖
为什么这样写是错的?始终想不明白。
备注:以0为超级源点方便统计答案,m已经在main()中+1。
siz[]:子树大小 f[节点][已选科数]
CPP
void dfs(int u,int fa)
{
	siz[u]=1;
	for(int e=fir[u];e;e=nex[e])
	{
		int v=to[e];
		if(v==fa) continue;
		dfs(v,u);
		siz[u]+=siz[v];
		if(siz[u]>m) siz[u]=m;
		for(int i=siz[u];i>=2;--i)
		{
			int tmp=min(i-1,siz[v]);
			for(int j=0;j<=tmp;++j)
				f[u][i]=max(f[u][i],f[v][j]+f[u][i-j-1]); //给点u腾一个位置,-1
		}
	}
	for(int i=1;i<=siz[u];++i) f[u][i]+=val[u]; //最后再把节点u的贡献加上
}
这样子就对了:
CPP
void dfs(int u,int fa)
{
	siz[u]=1;
	f[u][1]=val[u]; //背包预处理
	for(int e=fir[u];e;e=nex[e])
	{
		int v=to[e];
		if(v==fa) continue;
		dfs(v,u);
		siz[u]+=siz[v];
		if(siz[u]>m) siz[u]=m;
		for(int i=siz[u];i>=2;++i)
		{
			int tmp=min(i-1,siz[v]);
			for(int j=0;j<=tmp;++j)
				f[u][i]=max(f[u][i],f[v][j]+f[u][i-j]);
		}
	}
}
But Why? qwq

回复

1 条回复,欢迎继续交流。

正在加载回复...