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]\)要满足条件就需要满足所有前缀和 ...
随机推荐
- One usage of recurison: the tower of Hanoi
Statements: This blog was written by me, but most of content is quoted from book[Data Structure wit ...
- Java依照List内存储的对象的某个字段进行排序
关键点:将List内存储的对象实现Comparable类.重写它的compareTo()方法就可以 Bean: package chc; public class StuVo implements C ...
- 通过路由管理视图间切换 - AngularJS路由解析
模板的视图刷新 ng-view这个指令和路由组合之后就可以将$route对应的视图放入指定的HTML中,这一过程中它会创建自己的作用域并将模板嵌套在内部. ng-view指令的优先级是1000(终极) ...
- EOF需要两次才能结束输入
.EOF作为文件结束符时的情况: EOF虽然是文件结束符,但并不是在任何情况下输入Ctrl+D(Windows下Ctrl+Z)都能够实现文件结束的功能,只有在下列的条件下,才作为文件结束符.(1)遇 ...
- 去除input框的值
onfocus="this.value=' ';" <input type="text" name="buynum" id=" ...
- 网络协议之rtp---h264的rtp网络协议实现
完整的C/S架构的基于RTP/RTCP的H.264视频传输方案.此方案中,在服务器端和客户端分别进行了功能模块设计.服务器端:RTP封装模块主要是对H.264码流进行打包封装:RTCP分析模块负责产牛 ...
- 【剑指Offer学习】【面试题62:序列化二叉树】
题目:请实现两个函数,分别用来序列化和反序列化二叉树. 解题思路 通过分析解决前面的面试题6.我们知道能够从前序遍历和中序遍历构造出一棵二叉树.受此启示.我们能够先把一棵二叉树序列化成一个前序遍历序列 ...
- “checkbox”和“select”对象在javascript和jquery的操作差异做了整理
checkbox checkbox在javascript和jquery中选中和取消的方法 Javascript: document.getElementById("myCheck" ...
- 生成ssh密钥
打开Git Bash,生成ssh密钥: ssh-keygen -t rsa -C "your_email@youremail.com"
- EasyDarwin云存储方案调研:海康萤石云采用的是MPEG-PS打包的方式进行的存储
EasyDarwin开源流媒体服务器项目在直播功能稳定和完善之后,开始涉及服务器端存储与回放功能的调研与开发,当然,这里就要研究一下行业标杆萤石云是怎么来做的,我们通过非常复杂的流程将萤石存储的录像文 ...