[WC2008]游览计划(状压dp)
题面太鬼畜不粘了。
题意就是给一张n*m的网格图,每个点有点权,有k个关键点,让你把这k个关键点连成一个联通快的最小代价。
题解
这题nmk都非常小,解法肯定是状压,比较一般的解法插头dp,但不太好写。
但其实这道题是裸的斯坦纳树模型。
斯坦纳树是最小生成树的变形,在一般情况下是NP问题,但在k规模较少时可以用状压dp求解。
我们可以设dp[i][j][s]表示以(i,j)为根,覆盖关键点集合为s时的最小代价。
对于这个状态内部的更新,我们可以对s枚举子集,相当于把联通块拆成两部分再合并起来,dp[i][j][s] <= dp[i][j][S]+dp[i][j][s^S]。其中S是子集。
对于这个状态对外的更新,我们可以对和根有连边的点转移,dp[i'][j'][s']=dp[i][j][s]+a[i][j]。其实令s=s‘也可以,反正到了s‘时也得更新。
这种dp方法的好处就是只保留了一个转移点,降掉了我们枚举转移点的复杂度。
代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#define mm make_pair
#define N 11
using namespace std;
queue<pair<int,int> >q;
int ans,dp[N][N][<<],n,m,a[N][N],tot;
bool tag[N][N];
const int dx[]={-,,,};
const int dy[]={,-,,};
struct node{
int x,y,s;
}pre[N][N][<<];
inline void spfa(int x,int y,int s){
q.push(mm(x,y));
while(!q.empty()){
int ux=q.front().first,uy=q.front().second;q.pop();
for(int i=;i<;++i){
int vx=ux+dx[i],vy=uy+dy[i];
if(vx>&&vy>&&vx<=n&&vy<=m);else continue;
if(dp[vx][vy][s]>dp[ux][uy][s]+a[vx][vy]){
dp[vx][vy][s]=dp[ux][uy][s]+a[vx][vy];
pre[vx][vy][s]=node{ux,uy,s};
q.push(mm(vx,vy));
}
}
}
}
inline void findans(int x,int y,int s){
tag[x][y]=;
if(!x||!y)return;
int i=pre[x][y][s].x,j=pre[x][y][s].y,S=pre[x][y][s].s;
if(i==x&&j==y)findans(i,j,S),findans(i,j,s^S);
else findans(i,j,S);
}
int main(){
memset(dp,0x3f,sizeof(dp));
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)
for(int j=;j<=m;++j){
scanf("%d",&a[i][j]);
if(!a[i][j])dp[i][j][<<tot]=,tot++;
else dp[i][j][]=a[i][j];
}
int ma=(<<tot)-;
for(int s=;s<=ma;++s){
for(int i=;i<=n;++i)
for(int j=;j<=m;++j){
for(int S=s;S;S=s&(S-))
if(dp[i][j][s]>dp[i][j][S]+dp[i][j][s^S]-a[i][j]){
dp[i][j][s]=dp[i][j][S]+dp[i][j][s^S]-a[i][j];
pre[i][j][s]=node{i,j,S};
}
spfa(i,j,s);
}
}
int ans=2e9,prx,pry;
for(int i=;i<=n;++i)for(int j=;j<=m;++j)
if(dp[i][j][ma]<ans){
ans=min(ans,dp[i][j][ma]);prx=i,pry=j;
}
findans(prx,pry,ma);
cout<<ans<<endl;
for(int i=;i<=n;++i){
for(int j=;j<=m;++j){
if(!a[i][j])printf("x");
else if(tag[i][j])printf("o");
else printf("_");
}
puts("");
}
return ;
}
[WC2008]游览计划(状压dp)的更多相关文章
- luogu4294 [WC2008]游览计划(状压DP/斯坦纳树)
link 题目大意:给定一个网格图,有些点是关键点,选择格点有代价,求把所有关键点联通的最小代价 斯坦纳树模板题 斯坦纳树问题:给定一个图结构,有一些点是关键点,求把这些关键点联通的最小代价e 斯坦纳 ...
- [WC2008]游览计划 状压DP,斯坦纳树
---题面--- 题解: 这是一道斯坦纳树的题,用状压+spfa来解决 什么是斯坦纳树? 一开始还以为是数据结构来着,其实跟最小生成树很像,大致就是最小生成树只能在各个点之间直接相连,而斯坦纳树则允许 ...
- 【BZOJ 2595】2595: [Wc2008]游览计划 (状压DP+spfa,斯坦纳树?)
2595: [Wc2008]游览计划 Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 1572 Solved: 7 ...
- BZOJ2595 Wc2008 游览计划 【斯坦纳树】【状压DP】*
BZOJ2595 Wc2008 游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个 ...
- BZOJ 2595: [Wc2008]游览计划 [DP 状压 斯坦纳树 spfa]【学习笔记】
传送门 题意:略 论文 <SPFA算法的优化及应用> http://www.cnblogs.com/lazycal/p/bzoj-2595.html 本题的核心就是求斯坦纳树: Stein ...
- 【BZOJ2595_洛谷4294】[WC2008]游览计划(斯坦纳树_状压DP)
上个月写的题qwq--突然想写篇博客 题目: 洛谷4294 分析: 斯坦纳树模板题. 简单来说,斯坦纳树问题就是给定一张有边权(或点权)的无向图,要求选若干条边使图中一些选定的点连通(可以经过其他点) ...
- [WC2008]游览计划 解题报告
[WC2008]游览计划 斯坦纳树板子题,其实就是状压dp 令\(dp_{i,s}\)表示任意点\(i\)联通关键点集合\(s\)的最小代价 然后有转移 \[ dp_{i,S}=\min_{T\in ...
- bzoj2595 / P4294 [WC2008]游览计划
P4294 [WC2008]游览计划 斯坦纳树 斯坦纳树,是一种神奇的树.它支持在一个连通图上求包含若干个选定点的最小生成树. 前置算法:spfa+状压dp+dfs(大雾) 我们设$f[o][P]$为 ...
- 【bzoj4006】[JLOI2015]管道连接 斯坦纳树+状压dp
题目描述 给出一张 $n$ 个点 $m$ 条边的无向图和 $p$ 个特殊点,每个特殊点有一个颜色.要求选出若干条边,使得颜色相同的特殊点在同一个连通块内.输出最小边权和. 输入 第一行包含三个整数 n ...
随机推荐
- 6 Prefer and Would rather
1 prefer 使用 "prefer" 用来表明通常喜欢某件事甚于另一件事.说话者喜欢打高尔夫球更甚于喜欢打网球."prefer" 的后面可以接名词(&quo ...
- [转帖]IP /TCP协议及握手过程和数据包格式中级详解
IP /TCP协议及握手过程和数据包格式中级详解 https://www.toutiao.com/a6665292902458982926/ 写的挺好的 其实 一直没闹明白 网络好 广播地址 还有 网 ...
- Ajax发送请求等待时弹出模态框等待提示
主要的代码分为两块,一个是CSS定义模态框,另一个是在Ajax中弹出模态框. 查看菜鸟教程中的模态框教程demo,http://www.runoob.com/try/try.php?filename= ...
- vue图片被加了盗链
https://www.cnblogs.com/dongcanliang/archive/2017/04/01/6655061.html <meta name="referrer&qu ...
- Angular MVC
<!DOCTYPE html><html ng-app="myApp"><head lang="en"> <meta ...
- Struts2——通配符,Action Method_DMI
Action wildcard 通配符(配置量降到最低) 使用通配符,就是为了配置简便,但是一定遵守“约定优于配置”原则,约定就是做项目之前最好事先与项目组的人或是自己规定好命名规则. 多个* {1 ...
- git简介及安装(win10)
一句话介绍git Git是Linus Torvalds编写,目前是世界上最先进的分布式版本控制系统. git能干什么? 代码备份.还原,版本管理,分支管理,解决冲突,协同开发... 安装git > ...
- ArcGIS DeskTop 10.2 的安装与破解
ArcGIS DeskTop 10.2套件作为一组常用的ArcGIS软件为我们提供了对地图原始数据进行加工以及各种操作,通过这组软件我们能够很好地定制我们最终的地图样式,但是更多的时候我们需要对这组软 ...
- FormDestroy 和 FormClose 有什么区别和联系?
1.窗口的所有资源真正释放时调用 FormDestroy.当你关闭窗口时,VCL会调用FormClose,如果你在FormClose里写Action = caFree,那么VCL会继续调用FormDe ...
- 数据库迁移(创建关联等操作) Target database is not up to date报错
使用Mysql-sqlalchemy执行数据库迁移 来更新数据库: 队长试探性的在网上找了几种方案 依然没有解决报错问题: 后来看了https://www.aliyun.com/jiaocheng/4 ...