JZOJ 3419 最大利润#树形动态规划#

题目

政府邀请了你在火车站开饭店,但不允许同时在两个相连接的火车站开。任意两个火车站有且只有一条路径,每个火车站最多有50个和它相连接的火车站。
告诉你每个火车站的利润,问你可以获得的最大利润为多少。
如图

最佳投资方案是在1,2,5,6这4个火车站开饭店可以获得利润为90


分析

树形dp,f[i]表示选择这个车站的最大利润,g[i]表示不选择这个车站的最大利润
状态转移方程:

$ f[i]+=g[i.y] g[i]=max(f[i.y],g[i.y])$


代码

#include <cstdio> 
#include <algorithm>
#include <cctype>
using namespace std;
struct tree{
	int x,y,next;
}e[200001];
bool check[100001]; int ls[100001],pay[100001],f[100001],g[100001],n,m;
int in(){
	int ans=0; char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
	return ans;
}
bool dp(int x){
	if (check[x]) return 0;
	check[x]=1;
	int t=ls[x];
	while (t){
		if (dp(e[t].y)){
			f[x]+=g[e[t].y];
			g[x]+=max(f[e[t].y],g[e[t].y]);
		}
		t=e[t].next;
	}
	f[x]+=pay[x];
	return 1;
}
int main(){
	n=in(); for (int i=1;i<=n;i++) pay[i]=in(); m=(n-1)*2;
	for (int i=1;i<m;i+=2){
		e[i].x=e[i+1].y=in(); e[i].y=e[i+1].x=in();
		e[i].next=ls[e[i].x]; ls[e[i].x]=i;
e[i+1].next=ls[e[i+1].x]; ls[e[i+1].x]=i+1;//;邻接表
	}
	dp(1);
	printf("%d",max(f[1],g[1]));
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值