P1352 没有上司的舞会 解题报告(树形dp)

目录

  • 题目概述
  • 思路分析
  • ac代码

题目概述

https://www.luogu.com.cn/problem/P1352

思路分析

看到上司的下属之间的关系很容易想到树形结构,那么,又和最值挂钩,那么想到的就是树形dp。那么,这里的可以进行比较的点就是:上司参加,下属就不能参加,下属参加,上司一定不能参加,因此,状态转移的时候我们就需要比较的是上司去和不去的情况,所以,我们把dp数组的第二维开为2:存储上司不去(0)和去(1)时候的最大值。
若上司不去:下属可去可不去,那么,假设下属节点为v,我们要的就是max(dp[v][0],dp[v][1])的和。
若上司去,下属一定不去,那么,我们需要的就是dp[v][0]的和。因为快乐值可能减,所以,在加入上司的时候,还是要比较下val[u]和0的关系,确保值最大。
最后,每一次加完都和ans比较一下,最后输出就可以了

ac代码

#include 
#include 
using namespace std;
const int maxn=6e3+5;
struct Edge{
	int to;
	int next;
}; 
int cnt=0;
int head[maxn];
int w[maxn];
int du[maxn];
Edge e[maxn<<1];
int val[maxn][2]={0};
inline void add(int a,int b){
	e[cnt].to=b;
	e[cnt].next=head[a];
	head[a]=cnt++;
}
int ans=-INT_MAX;
void dfs(int u,int fa){
	int t1=0;
	int t2=0;
	for(int i=head[u];i!=-1;i=e[i].next){
		int v=e[i].to;
		if(v==fa) continue;
		dfs(v,u);
		t1+=max(val[v][0],val[v][1]);
		t2+=val[v][0];
	}
	val[u][0]=t1;
	val[u][1]=w[u]+t2;
	ans=max(val[u][0],val[u][1]);
}

int main()
{
	int n;
	cin>>n;
	for(int i=0;i<=n;i++) head[i]=-1;
	for(int i=1;i<=n;i++) cin>>w[i];
	for(int i=1;i<n;i++){
		int a,b;
		cin>>a>>b;
		add(a,b);
		add(b,a);
		du[a]++;
		du[b]++;
	}
	for(int i=1;i<=n;i++){
		if(du[i]==1){
			dfs(i,-1);
			break;
		}
	}
	cout<<ans<<endl;
	return 0;
}

你可能感兴趣的:(动态规划)