Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special Judge
Submit: 2030  Solved: 986
[Submit][Status][Discuss]

Description

Input

第一行有两个整数,N和 M,描述方块的数目。 
接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点;
否则表示控制该方块至少需要的志愿者数目。 相邻的整数用 (若干个) 空格隔开,
行首行末也可能有多余的空格。

Output

由 N + 1行组成。第一行为一个整数,表示你所给出的方案
中安排的志愿者总数目。 
接下来 N行,每行M 个字符,描述方案中相应方块的情况: 
z  ‘_’(下划线)表示该方块没有安排志愿者; 
z  ‘o’(小写英文字母o)表示该方块安排了志愿者; 
z  ‘x’(小写英文字母x)表示该方块是一个景点; 
注:请注意输出格式要求,如果缺少某一行或者某一行的字符数目和要求不
一致(任何一行中,多余的空格都不允许出现) ,都可能导致该测试点不得分。

Sample Input

4 4
0 1 1 0
2 5 5 1
1 5 5 1
0 1 1 0

Sample Output

6
xoox
___o
___o
xoox

HINT

对于100%的数据,N,M,K≤10,其中K为景点的数目。输入的所有整数均在[0,2^16]的范围内

Source

 
很明显是斯坦纳树
$f[i][j][sta]$表示$(i,j)$这个位置,与其他景点的连通性为$sta$时的最小花费
转移的时候一种是枚举子集
另一种是spfa判断,
比较套路
 
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int limit = ;
const int INF = 1e9;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') {x = x * + c - ''; c = getchar();}
return x * f;
}
#define MP(i,j) make_pair(i,j)
#define se second
#define fi first
#define Pair pair<int,int>
int N, M, tot = ;
int a[][], f[][][limit];
int xx[] = {-, +, , };
int yy[] = {, , -, +};
int vis[][];
struct PRE {
int x, y, S;
}Pre[][][limit];
queue<Pair>q;
void SPFA(int cur) {
while(q.size() != ) {
Pair p = q.front();q.pop();
vis[p.fi][p.se] = ;
for(int i = ; i <; i++) {
int wx = p.fi + xx[i], wy = p.se + yy[i];
if(wx < || wx > N || wy < || wy > M) continue;
if(f[wx][wy][cur] > f[p.fi][p.se][cur] + a[wx][wy]) {
f[wx][wy][cur] = f[p.fi][p.se][cur] + a[wx][wy];
Pre[wx][wy][cur] = (PRE){p.fi, p.se, cur};
if(!vis[wx][wy])
vis[wx][wy] = , q.push(MP(wx,wy));
}
}
}
}
void dfs(int x, int y, int now) {
vis[x][y] = ;
PRE tmp = Pre[x][y][now];
if(tmp.x == && tmp.y == ) return;
dfs(tmp.x, tmp.y, tmp.S);
if(tmp.x == x && tmp.y == y) dfs(tmp.x, tmp.y, now - tmp.S);
}
int main() {
N = read(); M = read();
memset(f, 0x3f, sizeof(f));
for(int i = ; i <= N; i++)
for(int j = ; j <= M; j++) {
a[i][j] = read();
if(a[i][j] == )
f[i][j][ << tot] = , tot++;
}
int limit = ( << tot) - ;
for(int sta = ; sta <= limit; sta++) {
for(int i = ; i<= N; i++)
for(int j = ; j <= M;j++) {
for(int s = sta & (sta - ); s; s = (s - ) & sta) {
if(f[i][j][s] + f[i][j][sta - s] - a[i][j] < f[i][j][sta])
f[i][j][sta] = f[i][j][s] + f[i][j][sta - s] - a[i][j],
Pre[i][j][sta] = (PRE){i,j,s};
}
if(f[i][j][sta] < INF) q.push(MP(i,j)), vis[i][j] = ;
}
SPFA(sta);
}
int ansx, ansy, flag = ;
for(int i = ; i <= N && !flag; i++)
for(int j = ; j <= M; j++)
if(!a[i][j])
{ansx = i, ansy = j; flag = ; break;}
printf("%d\n",f[ansx][ansy][limit]);
memset(vis, , sizeof(vis));
dfs(ansx, ansy, limit);
for(int i = ; i <= N; i++, puts("")) {
for(int j = ; j <= M; j++) {
if(a[i][j] == ) putchar('x');
else if(vis[i][j]) putchar('o');
else putchar('_');
}
}
return ;
}

BZOJ2595: [Wc2008]游览计划(斯坦纳树,状压DP)的更多相关文章

  1. bzoj2595 [Wc2008]游览计划——斯坦纳树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2595 今天刚学了斯坦纳树,还不太会,写一道题练习一下: 参考了博客:http://www.c ...

  2. bzoj2595: [Wc2008]游览计划 斯坦纳树

    斯坦纳树是在一个图中选取某些特定点使其联通(可以选取额外的点),要求花费最小,最小生成树是斯坦纳树的一种特殊情况 我们用dp[i][j]来表示以i为根,和j状态是否和i联通,那么有 转移方程: dp[ ...

  3. 【bzoj4006】[JLOI2015]管道连接 斯坦纳树+状压dp

    题目描述 给出一张 $n$ 个点 $m$ 条边的无向图和 $p$ 个特殊点,每个特殊点有一个颜色.要求选出若干条边,使得颜色相同的特殊点在同一个连通块内.输出最小边权和. 输入 第一行包含三个整数 n ...

  4. 【BZOJ2595】[Wc2008]游览计划 斯坦纳树

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

  5. Luogu 4294 [WC2008]游览计划 | 斯坦纳树

    题目链接 Luogu 4294 (我做这道题的时候BZOJ全站的SPJ都炸了 提交秒WA 幸好有洛谷) 题解 这道题是[斯坦纳树]的经典例题.斯坦纳树是这样一类问题:带边权无向图上有几个(一般约10个 ...

  6. 【BZOJ-2595】游览计划 斯坦纳树

    2595: [Wc2008]游览计划 Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 1518  Solved: 7 ...

  7. BZOJ 2595 [Wc2008]游览计划 ——斯坦纳树

    [题目分析] 斯坦纳树=子集DP+SPFA? 用来学习斯坦纳树的模板. 大概就是用二进制来表示树包含的点,然后用跟几点表示树的形态. 更新分为两种,一种是合并两个子集,一种是换根,换根用SPFA迭代即 ...

  8. P4294 [WC2008]游览计划 (斯坦纳树)

    题目链接 差不多是斯坦纳树裸题,不过边权化成了点权,这样在合并两棵子树时需要去掉根结点的权值,防止重复. 题目还要求输出解,只要在转移时记录下路径,然后dfs一遍就好了. #include<bi ...

  9. bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4006 [题意] 给定n点m边的图,连接边(u,v)需要花费w,问满足使k个点中同颜色的 ...

随机推荐

  1. SwipeRefreshLayout的高度测量

    感谢此作者的分享 http://www.cnblogs.com/linjzong/p/5221604.html 若SwipeRefreshLayout的子布局为一个线性布局LinearLayout, ...

  2. Android的onCreateOptionsMenu()创建菜单Menu

    android一共有三种形式的菜单:             1.选项菜单(optinosMenu)             2.上下文菜单(ContextMenu)             3.子菜 ...

  3. Linux+db2+was部署问题总结

     Linux+db2+was部署问题总结 前段日子在住建部进行了Linux环境下,db2+rbp+was的部署,由于是集群,切涉及到了很多was的东西,搞了很长时间,在此做一个问题总结,供后续查询 ...

  4. SqlSugarClientHelper

    using SqlSugar; using System; using System.Collections.Generic; using System.Configuration; using Sy ...

  5. RadioGroup实现类似ios的分段选择(UISegmentedControl)控件

    在ios7中有一种扁平风格的控件叫做分段选择控件UISegmentedControl,控件分为一排,横放着几个被简单线条隔开的按钮,每次点击只能选择其中一个按钮,他类似于tabbar但是又稍微有点区别 ...

  6. web.xml里welcome-file欢迎页面配置及web.xml简介

    web项目欢迎页面的配置 <welcome-file-list> <welcome-file>/WEB-INF/index.html</welcome-file> ...

  7. MQTT介绍(3)java模拟MQTT的发布,订阅

    MQTT目录: MQTT简单介绍 window安装MQTT服务器和client java模拟MQTT的发布,订阅 在此强调一下mqtt的使用场景: 1.不可靠.网络带宽小的网络 2.运行的设备CPU. ...

  8. ExpressRoute 先决条件和清单

    若要使用 ExpressRoute 连接到 Azure 服务,需确认是否符合以下部分中所列的要求. 帐户要求 使用中的有效 Azure 帐户.需有此帐户才能设置 ExpressRoute 线路. 连接 ...

  9. [翻译] SCViewShaker

    SCViewShaker https://github.com/rFlex/SCViewShaker About A highly configurable UIView category for s ...

  10. 文件夹名为单字符时右击弹出C++错误

    原因:操作系统安装有虚拟光驱软件——WinMount,此错误为WinMount的一个Bug 解决方法: 打开Windows注册表,定位此注册表并删除即可 [HKEY_CLASSES_ROOT\Dire ...