BZOJ2595 Wc2008 游览计划 【斯坦纳树】【状压DP】*
BZOJ2595 Wc2008 游览计划
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]的范围内
斯坦纳树,状压DP记录路径
还有一点小小的不同,就是这道题用子集信息进行更新的时候我们需要减去当前点的权值一次,因为两个子集都包含了这个点,权值多算了一次
有关斯坦纳树的总结,请看https://www.cnblogs.com/dream-maker-yk/p/9676340.html
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 11
struct Node{int x,y,s;};
int mx[]={0,0,1,-1};
int my[]={1,-1,0,0};
int n,m,maxs;
int cost[N][N],st[N][N],vis[N][N],cnt;
int d[N][N][1<<N];
Node pre[N][N][1<<N];
bool in[N][N][1<<N];
queue<Node> Q;
void SPFA(){
while(!Q.empty()){
Node t=Q.front();Q.pop();
int x=t.x,y=t.y,s=t.s;
in[x][y][s]=0;
for(int i=0;i<4;i++){
int tx=x+mx[i],ty=y+my[i],ts=s|st[tx][ty];
if(tx<1||tx>n||ty<1||ty>m)continue;
if(d[tx][ty][ts]>d[x][y][s]+cost[tx][ty]){
d[tx][ty][ts]=d[x][y][s]+cost[tx][ty];
pre[tx][ty][ts]=t;
if(!in[tx][ty][ts]&&s==ts){
in[tx][ty][ts]=1;
Q.push((Node){tx,ty,ts});
}
}
}
}
}
void dfs(int x,int y,int s){
vis[x][y]=1;
Node t=pre[x][y][s];
int tx=t.x,ty=t.y,ts=t.s;
if(!tx&&!ty&&!ts)return;
dfs(tx,ty,ts);
if(x==tx&&y==ty)dfs(x,y,(s-ts)|st[x][y]);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
scanf("%d",&cost[i][j]);
if(!cost[i][j])st[i][j]=1<<(cnt++);
}
maxs=(1<<cnt)-1;
memset(d,0x3f,sizeof(d));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(st[i][j])d[i][j][st[i][j]]=0;
for(int k=0;k<=maxs;k++){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(st[i][j]&&!(st[i][j]&k))continue;
for(int x=(k-1)&k;x;x=(x-1)&k){
int t=d[i][j][x|st[i][j]]+d[i][j][(k-x)|st[i][j]]-cost[i][j];
if(t<d[i][j][k]){
d[i][j][k]=t;
pre[i][j][k]=(Node){i,j,x|st[i][j]};
}
}
if(d[i][j][k]<INF){
Q.push((Node){i,j,k});
in[i][j][k]=1;
}
}
SPFA();
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)if(st[i][j]){
printf("%d\n",d[i][j][maxs]);
dfs(i,j,maxs);
for(int x=1;x<=n;x++){
for(int y=1;y<=m;y++){
if(st[x][y])putchar('x');
else if(vis[x][y])putchar('o');
else putchar('_');
}
putchar('\n');
}
return 0;
}
return 0;
}
BZOJ2595 Wc2008 游览计划 【斯坦纳树】【状压DP】*的更多相关文章
- BZOJ2595: [Wc2008]游览计划(斯坦纳树,状压DP)
Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 2030 Solved: 986[Submit][Status][ ...
- bzoj2595 [Wc2008]游览计划——斯坦纳树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2595 今天刚学了斯坦纳树,还不太会,写一道题练习一下: 参考了博客:http://www.c ...
- bzoj2595: [Wc2008]游览计划 斯坦纳树
斯坦纳树是在一个图中选取某些特定点使其联通(可以选取额外的点),要求花费最小,最小生成树是斯坦纳树的一种特殊情况 我们用dp[i][j]来表示以i为根,和j状态是否和i联通,那么有 转移方程: dp[ ...
- 【bzoj4006】[JLOI2015]管道连接 斯坦纳树+状压dp
题目描述 给出一张 $n$ 个点 $m$ 条边的无向图和 $p$ 个特殊点,每个特殊点有一个颜色.要求选出若干条边,使得颜色相同的特殊点在同一个连通块内.输出最小边权和. 输入 第一行包含三个整数 n ...
- 【BZOJ2595】[Wc2008]游览计划 斯坦纳树
[BZOJ2595][Wc2008]游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为 ...
- Luogu 4294 [WC2008]游览计划 | 斯坦纳树
题目链接 Luogu 4294 (我做这道题的时候BZOJ全站的SPJ都炸了 提交秒WA 幸好有洛谷) 题解 这道题是[斯坦纳树]的经典例题.斯坦纳树是这样一类问题:带边权无向图上有几个(一般约10个 ...
- 【BZOJ-2595】游览计划 斯坦纳树
2595: [Wc2008]游览计划 Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 1518 Solved: 7 ...
- BZOJ 2595 [Wc2008]游览计划 ——斯坦纳树
[题目分析] 斯坦纳树=子集DP+SPFA? 用来学习斯坦纳树的模板. 大概就是用二进制来表示树包含的点,然后用跟几点表示树的形态. 更新分为两种,一种是合并两个子集,一种是换根,换根用SPFA迭代即 ...
- P4294 [WC2008]游览计划 (斯坦纳树)
题目链接 差不多是斯坦纳树裸题,不过边权化成了点权,这样在合并两棵子树时需要去掉根结点的权值,防止重复. 题目还要求输出解,只要在转移时记录下路径,然后dfs一遍就好了. #include<bi ...
- bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4006 [题意] 给定n点m边的图,连接边(u,v)需要花费w,问满足使k个点中同颜色的 ...
随机推荐
- ubuntu install vue , vue-cli , how to create project..
<<install node.js <<the n model is manage the node.js version npm install -g n n stable ...
- MyEclipse2014.Maven自动更新
1.我把 "Do not automatically update dependencies from remote repositories" 和 "Download ...
- JavaScript权威指南--词法结构
使用广泛,所有的浏览器(桌面.手机.屏蔽等等)都配有相应的JavaScript解析器. JavaScript解析器如何工作? 浏览器在读取HTML文件的时候,只有当遇到<script>标签 ...
- form表单提交数据的数据格式
form表单提交的数据格式默认是 enctype="application/x-www-form-urlencoded"这样将input框的数据与input框的name属性以键值对 ...
- IEnumerable<T>作为方法返回值类型——建议通过yield return返回
若IEnumerable<T>作为方法返回值的类型,则建议使用“迭代”模式(yield return) private IEnumerable<TwoLevelTreeNodeVie ...
- Android之UI--打造12种Dialog对话框
最近有空,来把app中常用到的Dialog对话框写一篇博客,在app中很多地方都会用到Dialog对话框,今天小编我就给大家介绍Dialog对话框. 先看看效果图: 12种,可根据需求选择,上图可知, ...
- Mysql5.7-CentOS7安装
下载Mysql 官网地址,点击download,找到Community 选择MySQL Community Server 选择平台和版本下载即可 安装mysql 查看安装文档 在下载页面上面有安装指南 ...
- bind、delegate、on的区别
on(type,[data],fn) on有三个参数,type代表事件类型,可以为“click"."onchange"."mouseover" dat ...
- 51nod-1103-抽屉原理
1103 N的倍数 题目来源: Ural 1302 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 一个长度为N的数组A,从A中选出若干个数,使得 ...
- UVALive-4287 Proving Equivalences (有向图的强连通分量)
题目大意:有n个命题,已知其中的m个推导,要证明n个命题全部等价(等价具有传递性),最少还需要做出几次推导. 题目分析:由已知的推导可以建一张无向图,则问题变成了最少需要增加几条边能使图变成强连通图. ...