题目链接

BZOJ2595

题解

著名的斯坦纳树问题

设\(f[i][j][s]\)表示点\((i,j)\)与景点联通状况为\(s\)的最小志愿者数

设\(val[i][j]\)为\((i,j)\)需要的志愿者数

有两种转移

一种是自己转移

\[f[i][j][s] = min\{f[i][j][e] + f[i][j][\complement_s e] - val[i][j]\}
\]

一种是由周围转移过来

\[f[i][j][s] = min\{f[i][j][s] + f[x][y][s] + dis\}
\]

第一种\(O(3^{K})\)枚举子集,第二种就是最短路

纪念一下BZOJ500题,截个图,,数字挺整的

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#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 = 11,maxm = 1 << 10,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 n,m,K,maxv;
int f[maxn][maxn][maxm],val[maxn][maxn],id[maxn][maxn],vis[maxn][maxn];
int head,tail,X[4] = {0,0,-1,1},Y[4] = {-1,1,0,0};
int S[maxn][maxn];
cp q[10000];
struct tri{
int x,y,s;
};
vector<tri> pre[maxn][maxn][maxm];
void spfa(int s){
head = 0; tail = -1;
REP(i,n) REP(j,m) q[++tail] = mp(i,j),vis[i][j] = true;
cp u; int nx,ny;
while (head <= tail){
u = q[head++];
vis[u.first][u.second] = false;
for (int k = 0; k < 4; k++){
nx = u.first + X[k];
ny = u.second + Y[k];
if (nx < 1 || ny < 1 || nx > n || ny > m) continue;
if (f[nx][ny][s] > f[u.first][u.second][s] + val[nx][ny]){
f[nx][ny][s] = f[u.first][u.second][s] + val[nx][ny];
pre[nx][ny][s].clear();
pre[nx][ny][s].push_back((tri){u.first,u.second,s});
if (!vis[nx][ny]) q[++tail] = mp(nx,ny);
}
}
}
}
void dfs(int x,int y,int s){
S[x][y] = true;
tri u;
for (unsigned int i = 0; i < pre[x][y][s].size(); i++){
u = pre[x][y][s][i];
dfs(u.x,u.y,u.s);
}
}
void work(){
maxv = (1 << K) - 1;
memset(f,0x3f3f3f3f,sizeof(f));
REP(i,n) REP(j,m){
f[i][j][0] = 0;
if (!val[i][j]) f[i][j][1 << id[i][j] - 1] = 0;
}
for (int s = 0; s <= maxv; s++){
REP(i,n) REP(j,m){
for (int e = s; e; e = (e - 1) & s){
if (f[i][j][s] > f[i][j][e] + f[i][j][s ^ e] - val[i][j]){
f[i][j][s] = f[i][j][e] + f[i][j][s ^ e] - val[i][j];
pre[i][j][s].clear();
pre[i][j][s].push_back((tri){i,j,e});
pre[i][j][s].push_back((tri){i,j,s ^ e});
}
}
}
spfa(s);
}
int ans = INF,x,y;
REP(i,n) REP(j,m) if (ans > f[i][j][maxv]) ans = f[i][j][maxv],x = i,y = j;
printf("%d\n",ans);
dfs(x,y,maxv);
REP(i,n){
REP(j,m){
if (id[i][j]) putchar('x');
else if (S[i][j]) putchar('o');
else putchar('_');
}
puts("");
}
}
int main(){
n = read(); m = read();
REP(i,n) REP(j,m){
val[i][j] = read();
if (!val[i][j]) id[i][j] = ++K;
}
work();
return 0;
}

BZOJ2595 [Wc2008]游览计划 【状压dp + 最短路】的更多相关文章

  1. [WC2008]游览计划(状压dp)

    题面太鬼畜不粘了. 题意就是给一张n*m的网格图,每个点有点权,有k个关键点,让你把这k个关键点连成一个联通快的最小代价. 题解 这题nmk都非常小,解法肯定是状压,比较一般的解法插头dp,但不太好写 ...

  2. luogu4294 [WC2008]游览计划(状压DP/斯坦纳树)

    link 题目大意:给定一个网格图,有些点是关键点,选择格点有代价,求把所有关键点联通的最小代价 斯坦纳树模板题 斯坦纳树问题:给定一个图结构,有一些点是关键点,求把这些关键点联通的最小代价e 斯坦纳 ...

  3. [WC2008]游览计划 状压DP,斯坦纳树

    ---题面--- 题解: 这是一道斯坦纳树的题,用状压+spfa来解决 什么是斯坦纳树? 一开始还以为是数据结构来着,其实跟最小生成树很像,大致就是最小生成树只能在各个点之间直接相连,而斯坦纳树则允许 ...

  4. BZOJ2595 Wc2008 游览计划 【斯坦纳树】【状压DP】*

    BZOJ2595 Wc2008 游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个 ...

  5. 旅游(CSUST省赛选拔赛2+状压dp+最短路)

    题目链接:http://csustacm.com:4803/problem/1016 题目: 思路:状压dp+最短路,比赛的时候有想到状压dp,但是最短路部分写挫了,然后就卡死了,对不起出题人~dis ...

  6. BZOJ2595 WC2008游览计划(斯坦纳树)

    斯坦纳树板子题. 考虑状压dp,设f[i][j][S]表示当前在点(i,j)考虑转移,其所在的联通块包含的关键点集(至少)为S的答案. 转移时首先枚举子集,有f[i][j][S]=min{f[i][j ...

  7. 斯坦纳树 [bzoj2595][wc2008]游览计划 题解

    话说挺早就写过斯坦纳树了,不过当时没怎么总结,也不是很理解……现在来个小结吧~ 斯坦纳树就是包含给定点的最小生成树(个人理解权值应当为正). 一般来讲,给定点的数目应该很小吧...于是我们可以用状压D ...

  8. [bzoj2595][WC2008]游览计划/[bzoj5180][Baltic2016]Cities_斯坦纳树

    游览计划 bzoj-2595 wc-2008 题目大意:题目链接.题目连接. 注释:略. 想法:裸题求斯坦纳树. 斯坦纳树有两种转移方式,设$f[s][i]$表示联通状态为$s$,以$i$为根的最小代 ...

  9. Codeforces 375C - Circling Round Treasures(状压 dp+最短路转移)

    题面传送门 注意到这题中宝藏 \(+\) 炸弹个数最多只有 \(8\) 个,故考虑状压,设 \(dp[x][y][S]\) 表示当前坐标为 \((x,y)\),有且仅有 \(S\) 当中的物品被包围在 ...

随机推荐

  1. 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)

    最近接触过几个版本的cocos2dx,决定每个大变动的版本都尝试一下.本实例模仿微信5.0版本中的飞机大战游戏,如图: 一.工具 1.素材:飞机大战的素材(图片.声音等)来自于网络 2.引擎:coco ...

  2. oracle 查看锁表及解锁的语句

    解锁语句: alter system kill session 'sid, serial#'; alter system kill session '23, 1647'; 查询那些对象被锁: sele ...

  3. http 502 bad gate way

    世界杯期间,公司的cdn在回源时突然出现大量502. 刚出现问题时,因为考虑到一般502都是上游服务器出现问题,然后因为已经服务了很久都没有出现过这种问题, 就没有仔细考虑,就让回源中心的同事进行排查 ...

  4. Adobe InDesign CS6自学入门到高级视频教程

    关键字:Adobe InDesign 视频教程 点击获取视频教程 教程目录 第1章/1.卸载InDesign CS6.avi 第1章/2.安装InDesign CS6.avi 第2章/1.创建并编辑自 ...

  5. Nginx连载

    一. nginx变量(用户变量.内建变量) 用户变量 又称用户自定义变量 Nginx用户变量的可见范围是整个配置文件,甚至可以跨越不通虚拟主机的server配置,但是变量适用范围是不可以跨越自己的容器 ...

  6. Linux学习——echo和read命令用法

    转载自http://www.runoob.com/linux/linux-comm-read.html http://www.178linux.com/76331 echo命令 本文列举了echo命令 ...

  7. scrum立会报告+燃尽图(第三周第四次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2286 项目地址:https://coding.net/u/wuyy694 ...

  8. C++ Primer Plus学习:第三章

    C++入门第三章:处理数据 面向对象编程(OOP)的本质是设计并扩展自己的数据类型. 内置的C++数据类型分为基本类型和复合类型. 基本类型分为整数和浮点数. 复合类型分为数组.字符串.指针和结构. ...

  9. java 抽象类&接口

    1,抽象类中有构造函数吗? 有,用于给子类对象进行初始化.   2,抽象关键字不可以和那些关键字共存? private 不行 static 不行 final 不行   final关键字: 1,fina ...

  10. DELL服务器PXE前期处理

    thaks:https://www.cnblogs.com/520ZXL/ PXE批量推系统,服务器要具备条件:raid处理好,设置为pxe启动,与PXE服务器网络要通 先进入磁盘阵列(ctrl+R) ...