[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 ...
随机推荐
- marMariaDB & MYSQL flexviews
Using Flexviews - part one, introduction to materialized views - Percona Database Performance Bloght ...
- 【Python3练习题 016】 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
这题得倒着推.第10天还没吃,就剩1个,说明第9天吃完一半再吃1个还剩1个,假设第9天还没吃之前有桃子p个,可得:p * 1/2 - 1 = 1,可得 p = 4.以此类推,即可手算出. 代码思路为: ...
- [转帖]HTTP 头部解释
HTTP 头部解释 https://www.cnblogs.com/poissonnotes/p/4844014.html 之前看的太粗了 同事闻起来 referer 才知道自己所知甚少.. ==== ...
- Oracle pivot行转列函数案例
with temp as( select '湖北省' province,'武汉市' city,'第一' ranking from dual union all select '湖北省' provinc ...
- 动态SQL1
If标签 动态SQL可以说是MyBatis最强大之处了,这块的应用主要有四个方面if,choose,trim和foreach,接下来先说说if. 顾名思义,if是用来判断条件的,现在假设我们有个需求, ...
- Failed to bind properties under 'spring.datasource' to javax.sql.DataSource
这是我的配置文件 # 国际化配置文件(包名.基础名) spring.messages.basename=i18n.login server.tomcat.uri-encoding=UTF- sprin ...
- python爬虫之Anaconda安装
Anaconda概述 Anaconda是一个用于科学计算的Python发行版,支持 Linux, Mac, Windows系统,提供了包管理与环境管理的功能,可以很方便地解决多版本python并存.切 ...
- laravel 守护进程Supervisor的配置
安装Supervisor Supervisor是Linux系统中常用的进程守护程序.如果队列进程queue:work意外关闭,它会自动重启启动队列进程.在Ubuntu安装Supervisor 非常简单 ...
- 关于IWMS后台登录问题总结
一.登录后台,点击登录无反应: 1.是因为网站文件夹没有权限,需要右击文件夹,将只读勾选去掉 2.在安全中加入Everyone对象. 二.登录后台后,左边显示不全,是因为会员权限不够,需要给权限.
- vue開發環境搭建
npm(node package manager),nodejs的包管理器,用於nodejs插件的安裝.卸載和管理依賴. 安裝npm: 檢查npm是否安裝成功及版本:npm -v 卸載npm: 更新n ...