bzoj3836
状压dp
图上怎么跑dp?我们跑三进制状压dp,0表示选了,1表示既没选也没覆盖,2表示没选但是被覆盖了。
状态是dp[dep][S]表示当前走到了深度为dep的节点,状态为S,按照dfs序转移
每次转移就是计算这个点选了没选,然后像树形dp一样更新节点
返祖边也要处理
#include<bits/stdc++.h>
using namespace std;
const int N = 5e4 + ;
int n, m, ans;
vector<int> G[N];
int dp[][N], c[N], vis[N], bin[], st[N], d[N];
inline int rd()
{
int x = , f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = x * + c - ''; c = getchar(); }
return x * f;
}
int bit(int S, int t)
{
return S / bin[t] % ;
}
void dfs(int u, int dep)
{
vis[u] = ;
d[u] = dep;
if(!dep)
{
dp[][] = c[u];
dp[][] = ;
dp[][] = 1e9;
}
else
{
int top = ;
for(int i = ; i < G[u].size(); ++i)
{
int v = G[u][i];
if(d[v] < d[u] && vis[v]) st[++top] = d[v];
}
for(int i = ; i < bin[dep + ]; ++i) dp[dep][i] = 1e9;
for(int i = ; i < bin[dep]; ++i)
{
int U = , V = i;
for(int j = ; j <= top; ++j) if(bit(i, st[j]) == ) U = ; else if(bit(i, st[j]) == ) V += bin[st[j]];
dp[dep][i + U * bin[dep]] = min(dp[dep][i + U * bin[dep]], dp[dep - ][i]);
dp[dep][V] = min(dp[dep][V], dp[dep - ][i] + c[u]);
}
}
for(int i = ; i < G[u].size(); ++i)
{
int v = G[u][i];
if(vis[v]) continue;
dfs(v, dep + );
for(int j = ; j < bin[dep + ]; ++j) dp[dep][j] = min(dp[dep + ][j], dp[dep + ][j + * bin[dep + ]]);
}
}
int main()
{
n = rd();
m = rd();
bin[] = ;
for(int i = ; i <= ; ++i) bin[i] = bin[i - ] * ;
for(int i = ; i <= n; ++i) c[i] = rd();
for(int i = ; i <= m; ++i)
{
int u = rd(), v = rd();
G[u].push_back(v);
G[v].push_back(u);
}
for(int i = ; i <= n; ++i) if(!vis[i])
{
dfs(i, );
ans += min(dp[][], dp[][]);
}
printf("%d\n", ans);
return ;
}
bzoj3836的更多相关文章
- BZOJ3836 [Poi2014]Tourism 【树形dp +状压dp】
题目链接 BZOJ3836 题解 显然这是个\(NP\)完全问题,此题的解决全仗任意两点间不存在节点数超过10的简单路径的性质 这意味着什么呢? \(dfs\)树深度不超过\(10\) \(10\)很 ...
- BZOJ3836 : [Poi2014]Tourism
对于一个连通块,取一个点进行dfs,得到一棵dfs搜索树,则这棵树的深度不超过10,且所有额外边都是前向边. 对于每个点x,设S为三进制状态,S第i位表示根到x路径上深度为i的点的状态: 0:选了 1 ...
- OI动态规划&&优化 简单学习笔记
持续更新!! DP的难点主要分为两类,一类以状态设计为难点,一类以转移的优化为难点. DP的类型 序列DP [例题]BZOJ2298 problem a 数位DP 常用来统计或者查找一个区间满足条件的 ...
- POI2014题解
POI2014题解 [BZOJ3521][Poi2014]Salad Bar 把p当作\(1\),把j当作\(-1\),然后做一遍前缀和. 一个合法区间\([l,r]\)要满足条件就需要满足所有前缀和 ...
随机推荐
- 使用Cout输出String和CString对象
CString和string都是一个类,不同的是CString主要用于MFC或者是ATL编程中,而string则多用于Windows控制台编程中 在实际编程过程中,我们经常用到string或者是CSt ...
- PCB常用单位转换 mil 英尺
PCB常用单位转换 mil 英尺 相关常用单位 1mil = 0.0254mm 100mil = 2.54mm 1英寸 = 1000mil = 2.54cm 1英尺 = 12英寸 ...
- 轻松搞定RabbitMQ(二)——工作队列之消息分发机制
转自 http://blog.csdn.net/xiaoxian8023/article/details/48681987 上一篇博文中简单介绍了一下RabbitMQ的基础知识,并写了一个经典语言入门 ...
- Sublime Text3 配置设置攻略
转载:http://cloudbbs.org/forum.php?mod=viewthread&tid=3620 sublime本身功能有限,我们需要装上一些插件使其变得强大.sublime在 ...
- MVC准备工作
准备工作 打开VS创建一个ASP.NET MVC空项目,在http://www.asp.net/mvc/overview/getting-started/introduction/getting-st ...
- 说说设计模式~单件模式(Singleton)
单件模式(Singleton)要求一个类有且仅有一个实例,并且提供了一个全局的访问点. 从概念上来研究一下它的实现,不考虑线程安全 1 public sealed class Singlton 2 { ...
- 用live555将内网摄像机视频推送到外网服务器,附源码
最近很多人问,如何将内网的摄像机流媒体数据发布到公网,如果用公网与局域网间的端口映射方式太过麻烦,一个摄像机要做一组映射,而且不是每一个局域网都是有固定ip地址,即使外网主机配置好了每一个摄像机的映射 ...
- BZOJ3231: [Sdoi2008]递归数列
BZOJ3231: [Sdoi2008]递归数列 Description 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + ...
- tornado之运行第一个tornado程序
Tornado是使用Python编写的一个强大的.可扩展的Web服务器.它在处理严峻的网络流量时表现得足够强健,但却在创建和编写时有着足够的轻量级,并能够被用在大量的应用和工具中. 首先是安装torn ...
- MD5 字符串问题
早上来工位,大家再聊md5,无意中发现网上有个人提出个问题:研究了一下,挺有意思 有个串,通过各种办法得到的值不完全一样,下面请看细节: 假设这个字符串是 “ssss"我用的第一个办法应该是 ...