【BZOJ2595】 [Wc2008]游览计划
BZOJ2595 [Wc2008]游览计划
Solution
考虑这是一个最小费用连通性的问题,既然大家都说这是什么斯坦纳树那就是的吧...
所以我们肯定可以这样设一个dp状态:
\(dp_{i,j,k}\)表示经过点(i,j)且现在连通性为\(k\)的最小费用.
有两种转移方程:
\(dp_{i,j,k}=dp_{i,j,s}+dp_{i,j,k-s}-a[i][j];\)
\(dp_{i,j,k}=dp_{x,y,k}+a[i][j]\)
这个还是比较显然?
发现后面那个东西很像最短路不是吗?
直接SPFA+dp转移一下就好了.
代码实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
inline int gi()
{
int f=1,sum=0;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
const int N=20,Inf=1e9;
int bin[N],f[12][12][1024],vis[N][N];
int wa[4]={1,0,-1,0};
int lk[4]={0,1,0,-1};
struct node{
int a,b,c;
}pre[12][12][60010];
int a[N][N],n,m,b[N][N];
typedef pair<int,int> pii;
#define mp make_pair
queue<pii>Q;
void spfa(int s){
while(!Q.empty()){
pii now=Q.front();Q.pop();
int x=now.first,y=now.second;vis[x][y]=0;
for(int i=0;i<4;i++){
int xx=x+wa[i],yy=y+lk[i];
if(xx<1 || xx>n || yy<1 || yy>m)continue;
if(f[xx][yy][s]>f[x][y][s]+a[xx][yy]){
f[xx][yy][s]=f[x][y][s]+a[xx][yy];
pre[xx][yy][s]=(node){x,y,s};
if(!vis[xx][yy]){
vis[xx][yy]=1;Q.push(mp(xx,yy));
}
}
}
}
}
void dfs(int i,int j,int s)
{
if(i>=Inf || pre[i][j][s].c==0)return;
b[i][j]=1;node q=pre[i][j][s];
dfs(q.a,q.b,q.c);
if(q.a==i && q.b==j)dfs(i,j,s-q.c);
}
int main()
{
int K=0;
bin[0]=1;for(int i=1;i<20;i++)bin[i]=bin[i-1]<<1;
n=gi();m=gi();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
a[i][j]=gi();
if(!a[i][j])K++;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=0;k<bin[K];k++)
f[i][j][k]=pre[i][j][k].a=Inf;
K=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(!a[i][j])
f[i][j][bin[K]]=0,K++;
for(int s=1;s<bin[K];s++){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
for(int ss=s&(s-1);ss;ss=s&(ss-1)){
int t=f[i][j][ss]+f[i][j][s-ss]-a[i][j];
if(t<f[i][j][s]){
f[i][j][s]=t;pre[i][j][s]=(node){i,j,ss};
}
}
if(f[i][j][s]<Inf){
Q.push(mp(i,j));vis[i][j]=1;
}
}
spfa(s);
}
int x=0,y;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
if(!a[i][j]){
x=i;y=j;break;
}
if(x)break;
}
dfs(x,y,bin[K]-1);
printf("%d\n",f[x][y][bin[K]-1]);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
if(!a[i][j])putchar('x');
else if(b[i][j])putchar('o');
else putchar('_');
putchar('\n');
}
return 0;
}
【BZOJ2595】 [Wc2008]游览计划的更多相关文章
- BZOJ2595 Wc2008 游览计划 【斯坦纳树】【状压DP】*
BZOJ2595 Wc2008 游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个 ...
- [bzoj2595][WC2008]游览计划/[bzoj5180][Baltic2016]Cities_斯坦纳树
游览计划 bzoj-2595 wc-2008 题目大意:题目链接.题目连接. 注释:略. 想法:裸题求斯坦纳树. 斯坦纳树有两种转移方式,设$f[s][i]$表示联通状态为$s$,以$i$为根的最小代 ...
- BZOJ2595 WC2008游览计划(斯坦纳树)
斯坦纳树板子题. 考虑状压dp,设f[i][j][S]表示当前在点(i,j)考虑转移,其所在的联通块包含的关键点集(至少)为S的答案. 转移时首先枚举子集,有f[i][j][S]=min{f[i][j ...
- BZOJ2595 [Wc2008]游览计划 【状压dp + 最短路】
题目链接 BZOJ2595 题解 著名的斯坦纳树问题 设\(f[i][j][s]\)表示点\((i,j)\)与景点联通状况为\(s\)的最小志愿者数 设\(val[i][j]\)为\((i,j)\)需 ...
- bzoj2595 [Wc2008]游览计划——斯坦纳树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2595 今天刚学了斯坦纳树,还不太会,写一道题练习一下: 参考了博客:http://www.c ...
- BZOJ2595[WC2008]游览计划
Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点:否则表示控制该方块至少需要的志愿者数 ...
- 斯坦纳树 [bzoj2595][wc2008]游览计划 题解
话说挺早就写过斯坦纳树了,不过当时没怎么总结,也不是很理解……现在来个小结吧~ 斯坦纳树就是包含给定点的最小生成树(个人理解权值应当为正). 一般来讲,给定点的数目应该很小吧...于是我们可以用状压D ...
- bzoj2595: [Wc2008]游览计划 斯坦纳树
斯坦纳树是在一个图中选取某些特定点使其联通(可以选取额外的点),要求花费最小,最小生成树是斯坦纳树的一种特殊情况 我们用dp[i][j]来表示以i为根,和j状态是否和i联通,那么有 转移方程: dp[ ...
- BZOJ2595: [Wc2008]游览计划(斯坦纳树,状压DP)
Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 2030 Solved: 986[Submit][Status][ ...
随机推荐
- sim卡联系人name为空的问题。
1,之前的版本出现Bug:新建name为空的sim卡联系人,无法删除. 解决: 2,而后的版本出现新Bug:新建name不为空,Num不为空的sim卡联系人,然后编辑sim卡联系人,将Name清空,无 ...
- Easyui form 表单中的 radio 无法一开始就选中原因
是因为你在form表单里面,所以会出现样式没有选中状态,必须要从后台去获取数据,然后再绑定.也就是初始化数据.
- 2017/2/14:JSTL标签与el表达式
一.JSTL标签介绍 1.什么是JSTL? JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言!JSTL标签使用以来非常方便,它与JSP动作标签一样,只不过它不是 ...
- mybatis学习四 mybatis的三种查询方式
<select id="selAll" resultType="com.caopeng.pojo.Flower"> select * from fl ...
- canvas 实现时钟效果
var clock = document.getElementById('clock'); var cxt = clock.getContext('2d'); function drawClock() ...
- Codeforces 1107 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意简述:问你能不能把一个数字串切成若干块,使得切出来的kkk个数k≤2k\le2k≤2满足a1<a2<...&l ...
- 2019.01.08 codeforces 1009F. Dominant Indices(长链剖分)
传送门 长链剖分模板题. 题意:给出一棵树,设fi,jf_{i,j}fi,j表示iii的子树中距离点iii距离为jjj的点的个数,现在对于每个点iii要求出使得fif_ifi取得最大值的那个jjj ...
- 2018.10.27 bzoj3209: 花神的数论题(数位dp)
传送门 数位dpdpdp经典题. 题面已经暗示了我们按照二进制位来数位dpdpdp. 直接dpdpdp多少个数有111个111,222个111,333个111-, 然后快速幂算就行了. 于是我们枚举前 ...
- 简单实现"Tomcat"
Tomcat的主要功能就是接收客户端的Http请求,然后将请求分发,并且将请求封装,最后返回资源给到客户端.话不多说,开干. 一.实现设计图 (禁止盗图,除非先转支付宝!!!) ...
- CentOS 7 / RHEL 7 运行单用户模式进行root的密码重置
步骤一,开机时随便按下键盘,进入以下菜单 步骤二: 选择第一项,按e键进行修改 步骤三,定位到 ro( linux 16 or linuxefi ) 步骤四:把ro改成 “rw init=/sys ...