poj 2342/3342 树上的带权最大独立集(不与上司去吃饭)

博客介绍了如何使用树形动态规划解决树上的带权最大独立集问题,即在树状结构中邀请客人以最大化欢乐值,同时满足上下级不能同时参加的条件。此外,还讨论了无权情况下的独立数问题及其唯一性判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:宴会举办者要邀请一批客人,所有客人之间的关系可以看成一棵树,上层的监督下层的。已知直接相邻层的人不能被同时邀请,而且每个人有个欢乐值。问举办者如何邀请客人能满足上述条件,而且使得欢乐值最大。

思路:树形dp(树上的带权最大独立集问题)。从root开始搜索,dp[i][0]表示在以i为root的子树中不邀请i客人达到的最大欢乐值,dp[i][1]表示在以i为root的子树中邀请i客人达到的最大欢乐值。邀请了i,那么i的所有直接下层节点必然不能邀请,未邀请i,其直接下层节点可请可不请。

#include <stdio.h>
#include <string.h>
#define N 6005
#define max(a,b) ((a)>(b)?(a):(b))
struct edge{
	int y,next;
}e[N];
int dp[N][2],s[N],first[N],flag[N];
int n,top;
void add(int x,int y){
	e[top].y = y;
	e[top].next = first[x];
	first[x] = top++;
}
void dfs(int x){
	int i,y;
	dp[x][1] = s[x];
	for(i = first[x];i!=-1;i=e[i].next){
		y = e[i].y;
		dfs(y);
		dp[x][1]+=dp[y][0];
		dp[x][0]+=max(dp[y][0],dp[y][1]);
	}
}
int main(){
	freopen("a.txt","r",stdin);
	while(scanf("%d",&n)!=EOF){
		int i,a,b;
		memset(dp,0,sizeof(dp));
		memset(first,-1,sizeof(first));
		memset(flag,0,sizeof(flag));
		top = 0;
		for(i = 1;i<=n;i++)
			scanf("%d",&s[i]);
		for(i = 1;i<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值