【BZOJ 2595】2595: [Wc2008]游览计划 (状压DP+spfa,斯坦纳树?)
2595: [Wc2008]游览计划
Time Limit: 10 Sec Memory Limit: 256 MBSec Special Judge
Submit: 1572 Solved: 739Description
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 0Sample Output
6
xoox
___o
___o
xooxHINT
对于100%的数据,N,M,K≤10,其中K为景点的数目。输入的所有整数均在[0,2^16]的范围内
Source
【分析】
又是不会的一题啦~
斯坦纳树?smg?
刚开始看题可能觉得是最小生成树吧?但是并不是的。
一个条路径可能在最小生成树上面算几次,但是在这题上只算一次。
然后就是斯坦纳树??【长姿势??
反正就是,要覆盖的点很少<=10,可以状压这个,f[i][j][t]表示和(i,j)这个格子联通的需覆盖点集合为t的最小代价。
两个方程:
$f[i][j][t]=min(f[i][j][s]+f[i][j][t-ss])$ s是t的子集。
$f[i][j][t]=min(f[x][y][t]+a[i][j])$ (i,j)与(x,y)相邻
第二个式子啊不是普通的dp啊,转移状态的有环的!!但是,不怕,肯定是小的转到大的,然后一脸最短路的样子,就可以用spfa解决的。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define INF 0xfffffff int a[][],num[][],f[][][]; struct node {int x,y,d;};
node g[][][];
queue<node > q;
bool inq[][]; int bx[]={,,,-,},
by[]={,,,,-}; void dfs(int x,int y,int k)
{
if(!k) return;inq[x][y]=;
dfs(g[x][y][k].x,g[x][y][k].y,g[x][y][k].d);
if(g[x][y][k].x==x&&g[x][y][k].y==y) dfs(x,y,k-g[x][y][k].d);
} int main()
{
int n,m,cnt=;
scanf("%d%d",&n,&m);
memset(f,,sizeof(f));
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
scanf("%d",&a[i][j]);
if(a[i][j]==)
{
num[i][j]=++cnt;
f[i][j][<<cnt-]=;
g[i][j][<<cnt-].x=g[i][j][<<cnt-].y=g[i][j][<<cnt-].d=;
}
}
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) f[i][j][]=;
for(int k=;k<=(<<cnt)-;k++)
{
memset(inq,,sizeof(inq));
for(int ss=k;ss;ss=(ss-)&k)
{
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) //if(a[i][j]==0)
{
if(f[i][j][k]>f[i][j][ss]+f[i][j][k-ss]-a[i][j])
{
f[i][j][k]=f[i][j][ss]+f[i][j][k-ss]-a[i][j];
node nw;
nw.x=i;nw.y=j;nw.d=ss;
g[i][j][k]=nw;
}
if(f[i][j][k]<INF) {node nw;nw.x=i;nw.y=j;nw.d=f[i][j][k];inq[i][j]=;q.push(nw);}
} }
while(!q.empty())
{
node x=q.front();
for(int i=;i<=;i++)
{
int nx=x.x+bx[i],ny=x.y+by[i];
if(nx<||nx>n||ny<||ny>m) continue;
if(f[nx][ny][k]>f[x.x][x.y][k]+a[nx][ny])
{
f[nx][ny][k]=f[x.x][x.y][k]+a[nx][ny];
node nw;
nw.x=nx;nw.y=ny;//nw.d=f[nx][ny][k];
// g[nx][ny][k]=g[x.x][x.y][k];
g[nx][ny][k].x=x.x;g[nx][ny][k].y=x.y;g[nx][ny][k].d=k;
if(!inq[nx][ny])
{
inq[nx][ny]=;
q.push(nw);
}
}
}
q.pop();inq[x.x][x.y]=;
}
}
memset(inq,,sizeof(inq));
bool ok=;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++) if(a[i][j]==)
{
printf("%d\n",f[i][j][(<<cnt)-]);
dfs(i,j,(<<cnt)-);
ok=;break;
}
if(ok) break;
} for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(a[i][j]==) printf("x");
else if(inq[i][j]) printf("o");
else printf("_");
}
printf("\n");
}
return ;
}
2017-04-05 19:28:31
【BZOJ 2595】2595: [Wc2008]游览计划 (状压DP+spfa,斯坦纳树?)的更多相关文章
- [WC2008]游览计划 状压DP,斯坦纳树
---题面--- 题解: 这是一道斯坦纳树的题,用状压+spfa来解决 什么是斯坦纳树? 一开始还以为是数据结构来着,其实跟最小生成树很像,大致就是最小生成树只能在各个点之间直接相连,而斯坦纳树则允许 ...
- [WC2008]游览计划(状压dp)
题面太鬼畜不粘了. 题意就是给一张n*m的网格图,每个点有点权,有k个关键点,让你把这k个关键点连成一个联通快的最小代价. 题解 这题nmk都非常小,解法肯定是状压,比较一般的解法插头dp,但不太好写 ...
- luogu4294 [WC2008]游览计划(状压DP/斯坦纳树)
link 题目大意:给定一个网格图,有些点是关键点,选择格点有代价,求把所有关键点联通的最小代价 斯坦纳树模板题 斯坦纳树问题:给定一个图结构,有一些点是关键点,求把这些关键点联通的最小代价e 斯坦纳 ...
- 【BZOJ2595】游览计划(状压DP,斯坦纳树)
题意:见题面(我发现自己真是越来越懒了) 有N*M的矩阵,每个格子有一个值a[i,j] 现要求将其中的K个点(称为关键点)用格子连接起来,取(i,j)的费用就是a[i,j] 求K点全部连通的最小花费以 ...
- [BZOJ 1072] [SCOI2007] 排列perm 【状压DP】
题目链接:BZOJ 1072 这道题使用 C++ STL 的 next_permutation() 函数直接暴力就可以AC .(使用 Set 判断是否重复) 代码如下: #include <io ...
- BZOJ 3195 [Jxoi2012]奇怪的道路 | 状压DP
传送门 BZOJ 3195 题解 这是一道画风正常的状压DP题. 可以想到,\(dp[i][j][k]\)表示到第\(i\)个点.已经连了\(j\)条边,当前\([i - K, i]\)区间内的点的度 ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- BZOJ 3446: [Usaco2014 Feb]Cow Decathlon( 状压dp )
水状压dp. dp(x, s) = max{ dp( x - 1, s - {h} ) } + 奖励(假如拿到的) (h∈s). 时间复杂度O(n * 2^n) ------------------- ...
- BZOJ 2734 [HNOI2012]集合选数 (状压DP、时间复杂度分析)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2734 题解 嗯早就想写的题,昨天因为某些不可告人的原因(大雾)把这题写了,今天再来写题解 ...
随机推荐
- (4.1)LingPipe在Eclipse中的运行
酒店评论情感分析系统(四)——LingPipe在Eclipse中的运行 本来打算在做这个项目的时候,使用基于语义的文本倾向性分析方法,即先通过对评论文本进行中文分析,去停用词,然后在倾向性语义模式库的 ...
- 巧用Javascript将相对路径地址转换为绝对路径
这里介绍的其实本质上是两种方法,通过创建DOM或通过JavaScript计算: 1)通过新创建的Image, 经测试会发送一个Aborted的请求,并且IE6不支持, 将new Image改成docu ...
- [php]apache的权限解释
格式如下: <Directory d:/...> Order allow,deny Allow from all Allow from 127.0.0.1 Deny from 110.0. ...
- MyBatis笔记之配置输出日志并打印输出SQL语句
1. 引入Log4J的Maven依赖: <dependency> <groupId>log4j</groupId> <artifactId>log4j& ...
- xp,win7,win10系统安装GHO镜像下载
淘宝买的纯净版系统镜像 不含任何垃圾软件 极致纯净 链接:http://pan.baidu.com/s/1eR12db0 密码:opjm 链接:http://pan.baidu.com/s/1mhEN ...
- 不相交集ADT--数组实现
不相交集是解决等价问题的一种有效的数据结构,之所以称之为有效是因为,这个数据结构简单(几行代码,一个简单数组就可以搞定),快速(每个操作基本上可以在常数平均时间内搞定). 首先我们要明白什么叫做等价关 ...
- 使用ctypes在Python中调用C++动态库
使用ctypes在Python中调用C++动态库 入门操作 使用ctypes库可以直接调用C语言编写的动态库,而如果是调用C++编写的动态库,需要使用extern关键字对动态库的函数进行声明: #in ...
- javascript反混淆之packed混淆(二)
上次我们简单的入门下怎么使用html破解packed的混淆,下面看一个综合案例. 上次内容javascript反混淆之packed混淆(一) function getKey() { var aaaaf ...
- gradle-4.1-rc-1-all.zip gradle-4.1-rc-2-all.zip 免费下载(百度网盘)
今天下载遇到官网不给力,给有需要的你 gradle-4.1-rc-1-all.zip 密码: uyey gradle-4.1-rc-2-all.zip 密码: txhh
- eclipse 常见问题之字体更改、添加注释模板
有些同学可能会和我有一样的困扰,每次想要更改字体大小.背景颜色等,都需要百度一下才知道怎么去做...不知道有没有这种情况的孩子,反正我经常遇到,老是记不住,今天写下来,顺带自己忘记的时候可以查看一下. ...