BZOJ3836 [Poi2014]Tourism 【树形dp +状压dp】
题目链接
题解
显然这是个\(NP\)完全问题,此题的解决全仗任意两点间不存在节点数超过10的简单路径的性质
这意味着什么呢?
\(dfs\)树深度不超过\(10\)
\(10\)很小呐,可以状压了呢
我们发现一个点不但收祖先影响,而且受儿子影响,比较难处理
我们就先处理该点及其祖先,然后更新完儿子之后反过来用儿子更新根,就使得全局合法了
一个点显然有三种状态:
0.没被覆盖
1.被覆盖但是没有建站
2.建站
设\(f[d][s]\)表示节点\(u\)【深度为\(d\)】,其祖先【包括\(u\)】状态为\(s\)的最优解
\(dfs\)进来的时候,我们用父亲的答案更新\(u\)
\(dfs\)结束的时候,我们用儿子的答案替代\(u\)的答案,保证全局合法
复杂度\(O((n + m)3^{10})\)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 20005,maxm = 50005,M = 59050,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int h[maxn],ne = 1;
int n,m,C[maxn],dep[maxn],vis[maxn],bin[100];
int f[11][M],st[maxn],top; //0 not yet 1 ok but empty 2 ok and full
struct EDGE{int to,nxt;}ed[maxm];
inline void build(int u,int v){
ed[++ne] = (EDGE){v,h[u]}; h[u] = ne;
ed[++ne] = (EDGE){u,h[v]}; h[v] = ne;
}
inline int min(int a,int b){return a < b ? a : b;}
void dfs(int u){
vis[u] = true;
int maxv = bin[dep[u]] - 1,d = dep[u]; top = 0;
for (int i = 0; i < bin[dep[u] + 1]; i++) f[d][i] = INF;
Redge(u) if (vis[to = ed[k].to]) st[++top] = dep[to];
if (!d) f[0][0] = 0,f[0][1] = INF,f[0][2] = C[u];
for (int s = 0; s <= maxv; s++){
int t = 0,v,p,e = s + 2 * bin[d];
REP(i,top){
v = st[i]; p = s / bin[v] % 3;
if (p == 2) t = 1;
else if (!p) e += bin[v];
}
f[d][s + t * bin[d]] = min(f[d][s + t * bin[d]],f[d - 1][s]);
f[d][e] = min(f[d][e],f[d - 1][s] + C[u]);
}
Redge(u) if (!vis[to = ed[k].to]){
dep[to] = dep[u] + 1;
dfs(to);
for (int s = 0; s < bin[d + 1]; s++)
f[d][s] = min(f[d + 1][s + bin[d + 1]],f[d + 1][s + 2 * bin[d + 1]]);
}
}
int main(){
bin[0] = 1; for (int i = 1; i <= 13; i++) bin[i] = bin[i - 1] * 3;
n = read(); m = read();
REP(i,n) C[i] = read();
while (m--) build(read(),read());
int ans = 0;
for (int i = 1; i <= n; i++)
if (!vis[i]) dfs(i),ans += min(f[0][1],f[0][2]);
printf("%d\n",ans);
return 0;
}
BZOJ3836 [Poi2014]Tourism 【树形dp +状压dp】的更多相关文章
- 【BZOJ】1076 [SCOI2008]奖励关 期望DP+状压DP
[题意]n种宝物,k关游戏,每关游戏给出一种宝物,可捡可不捡.每种宝物有一个价值(有负数).每个宝物有前提宝物列表,必须在前面的关卡取得列表宝物才能捡起这个宝物,求期望收益.k<=100,n&l ...
- CCF 201312-4 有趣的数 (数位DP, 状压DP, 组合数学+暴力枚举, 推公式, 矩阵快速幂)
问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高 ...
- hdu 4352 "XHXJ's LIS"(数位DP+状压DP+LIS)
传送门 参考博文: [1]:http://www.voidcn.com/article/p-ehojgauy-ot.html 题解: 将数字num字符串化: 求[L,R]区间最长上升子序列长度为 K ...
- [转]状态压缩dp(状压dp)
状态压缩动态规划(简称状压dp)是另一类非常典型的动态规划,通常使用在NP问题的小规模求解中,虽然是指数级别的复杂度,但速度比搜索快,其思想非常值得借鉴. 为了更好的理解状压dp,首先介绍位运算相关的 ...
- 状态压缩dp 状压dp 详解
说到状压dp,一般和二进制少不了关系(还常和博弈论结合起来考,这个坑我挖了还没填qwq),二进制是个好东西啊,所以二进制的各种运算是前置知识,不了解的话走下面链接进百度百科 https://baike ...
- 洛谷 P3343 - [ZJOI2015]地震后的幻想乡(朴素状压 DP/状压 DP+微积分)
题面传送门 鸽子 tzc 竟然来补题解了,奇迹奇迹( 神仙题 %%%%%%%%%%%% 解法 1: 首先一件很明显的事情是这个最小值可以通过类似 Kruskal 求最小生成树的方法求得.我们将所有边按 ...
- 51nod 1673 树有几多愁(链表维护树形DP+状压DP)
题意 lyk有一棵树,它想给这棵树重标号. 重标号后,这棵树的所有叶子节点的值为它到根的路径上的编号最小的点的编号. 这棵树的烦恼值为所有叶子节点的值的乘积. lyk想让这棵树的烦恼值最大,你只需输出 ...
- bzoj4455 & loj2091 [Zjoi2016]小星星 容斥原理+树形DP(+状压DP?)
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4455 https://loj.ac/problem/2091 题解 很不错的一道题.(不过在当 ...
- HDU 4049 Tourism Planning(状压DP)题解
题意:m个城市,n个人,让这n个人按固定顺序走遍m个城市.每个城市有一个单人票价pi.每个人在每个城市能获得vij的价值.如果多个人在同一城市,那么会额外获得价值,给出一张n * n价值表,额外价值为 ...
随机推荐
- AssociatedObject关联对象原理实现
介绍 关联对象(AssociatedObject)是Objective-C 2.0运行时的一个特性,允许开发者对已经存在的类在扩展中添加自定义的属性.在实际生产过程中,比较常用的方式是给分类(Cate ...
- yocto-sumo源码解析(八): ProcessServer
从前面章节的论述中,我们知道BitBakeServer实际上是一个ProcessServer,什么是ProcessServer不可不了解. 1. 类的声明: 首先这是一个python的多进程包里面的进 ...
- linux一切皆文件之文件描述符(一)
一.知识准备 1.在linux中,一切皆为文件,所有不同种类的类型都被抽象成文件.如:普通文件.目录.字符设备.块设备.套接字等 2.当一个文件被进程打开,就会创建一个文件描述符.这时候,文件的路径就 ...
- 图解 Go 并发
你很可能从某种途径听说过 Go 语言.它越来越受欢迎,并且有充分的理由可以证明. Go 快速.简单,有强大的社区支持.学习这门语言最令人兴奋的一点是它的并发模型. Go 的并发原语使创建多线程并发程序 ...
- 20162327WJH第一次实验——线性结构
20162327WJH第一次实验--线性结构 实 验 报 告 实 验 报 告 课程:程序设计与数据结构 班级: 1623 姓名: 王旌含 学号:20162327 成绩: 2分 指导教师:娄嘉鹏 王志强 ...
- 第一个Sprint冲刺成果
组长:李咏江,组员:叶煜稳,谢洪跃,周伟雄 进程:第一个算法功能完成
- User survey(用户调研)
郑文武——小学二年级学生 姓名 郑文武 性别.年龄 男.9岁 职业 学生 收入 父母给的零花钱 知识层次和能力 会使用手机 生活/工作情况 努力学习但数学成 ...
- What is ASP.NET SignalR
什么是ASP.NET SignalR ASP.NET SignalR是ASP.NET开发人员的新库,它使得为应用程序添加实时Web功能变得非常简单. 什么是“实时网络”功能?它能够让您的服务器端代码实 ...
- Alpha版本冲刺(六)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...
- Scrum 项目4.0&&5.0
MY—HR 成员: 角色分配 学号 博客园 4.0团队贡献分 5.0团队贡献分 丘惠敏 PM项目经理 201406114203 http://www.cnblogs.com/qiuhuimin/ 19 ...