BZOJ3836 [Poi2014]Tourism

简要题意:
给定一个n个点,m条边的无向图,其中你在第i个点建立旅游站点的费用为Ci。在这张图中,任意两点间不存在节点数超过10的简单路径。请找到一种费用最小的建立旅游站点的方案,使得每个点要么建立了旅游站点,要么与它有边直接相连的点里至少有一个点建立了旅游站点。
题解:
根据dfs搜索树进行树DP。
对一个点的影响不仅有它的儿子,还有它的祖先。
对每一个独立的联通块DP,令f[i][s]表示在dfs搜索树中深度为i的点,其祖先的状态为s。其中s是一个三进制数。对于s中每一位上,0表示该点选了,1表示该点未选且这个点不满足要求,2表示该点未选但这个点满足要求(即它的邻接点选了)。
第一种转移:节点u不选。
访问节点u,其深度为dep时,先找出它的邻接点且为它的祖先。
第一种转移:节点u不选。
若其中有一个点选了,则
f[dep][s+2∗pow[dep]]=min(f[dep][s+2∗pow[dep]],f[dep−1][s]);
否则f[dep][s+pow[dep]]=min(f[dep][s+pow[dep]],f[dep−1][s]+val[u]);
第二种转移:节点u选了。
那么将s中为1的点改成2即可。
对于它的儿子,直接用min(f[dep+1][s],f[dep+1][s+2∗pow[dep+1]])来更新f[dep][s]即可。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=20005,M=50010,K
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值