P4294 [WC2008]游览计划 (斯坦纳树)
差不多是斯坦纳树裸题,不过边权化成了点权,这样在合并两棵子树时需要去掉根结点的权值,防止重复。
题目还要求输出解,只要在转移时记录下路径,然后dfs一遍就好了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=+,inf=0x3f3f3f3f;
const int dx[]= {,,-,};
const int dy[]= {-,,,};
int n,m,k,dp[<<][N][N],a[N][N],inq[N][N];
char s[N][N];
struct D {int x,y;} X[N];
struct Ans {int S,x,y;} ansS,nxt[<<][N][N];
queue<D> q;
void upd(int x,int y,int c,int S,int x2,int y2) {
if(dp[S][x][y]>c) {
dp[S][x][y]=c;
nxt[S][x][y]= {S,x2,y2};
if(!inq[x][y])inq[x][y]=,q.push({x,y});
}
}
void spfa(int S) {
while(q.size())q.pop();
memset(inq,,sizeof inq);
for(int i=; i<=n; ++i)
for(int j=; j<=m; ++j)
if(dp[S][i][j]!=inf)inq[i][j]=,q.push({i,j});
while(q.size()) {
int x=q.front().x,y=q.front().y;
q.pop(),inq[x][y]=;
for(int i=; i<; ++i) {
int x2=x+dx[i],y2=y+dy[i];
if(x2<||x2>n||y2<||y2>m)continue;
upd(x2,y2,dp[S][x][y]+a[x2][y2],S,x,y);
}
}
}
void dfs(int S,int x,int y) {
if(!a[x][y])s[x][y]='x';
else s[x][y]='o';
int S2=nxt[S][x][y].S,x2=nxt[S][x][y].x,y2=nxt[S][x][y].y;
if(!S2)return;
else if(S2==S)dfs(S2,x2,y2);
else dfs(S2,x2,y2),dfs(S^S2,x2,y2);
}
int main() {
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])X[k++]= {i,j};
}
memset(dp,inf,sizeof dp);
for(int i=; i<k; ++i)dp[<<i][X[i].x][X[i].y]=a[X[i].x][X[i].y];
for(int S=; S<(<<k); ++S) {
for(int S2=(S-)&S; S2; S2=(S2-)&S)
for(int i=; i<=n; ++i)
for(int j=; j<=m; ++j) {
dp[S][i][j]=min(dp[S][i][j],dp[S2][i][j]+dp[S^S2][i][j]-a[i][j]);
if(dp[S][i][j]==dp[S2][i][j]+dp[S^S2][i][j]-a[i][j])nxt[S][i][j]= {S2,i,j};
}
spfa(S);
}
int ans=inf;
for(int i=; i<=n; ++i)
for(int j=; j<=m; ++j) {
ans=min(ans,dp[(<<k)-][i][j]);
if(ans==dp[(<<k)-][i][j])ansS= {(<<k)-,i,j};
}
for(int i=; i<=n; ++i)
for(int j=; j<=m; ++j)s[i][j]='_';
dfs(ansS.S,ansS.x,ansS.y);
printf("%d\n",ans);
for(int i=; i<=n; ++i) {
for(int j=; j<=m; ++j)putchar(s[i][j]);
puts("");
}
return ;
}
P4294 [WC2008]游览计划 (斯坦纳树)的更多相关文章
- 【BZOJ2595】[Wc2008]游览计划 斯坦纳树
[BZOJ2595][Wc2008]游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为 ...
- Luogu 4294 [WC2008]游览计划 | 斯坦纳树
题目链接 Luogu 4294 (我做这道题的时候BZOJ全站的SPJ都炸了 提交秒WA 幸好有洛谷) 题解 这道题是[斯坦纳树]的经典例题.斯坦纳树是这样一类问题:带边权无向图上有几个(一般约10个 ...
- 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][ ...
- BZOJ 2595 [Wc2008]游览计划 ——斯坦纳树
[题目分析] 斯坦纳树=子集DP+SPFA? 用来学习斯坦纳树的模板. 大概就是用二进制来表示树包含的点,然后用跟几点表示树的形态. 更新分为两种,一种是合并两个子集,一种是换根,换根用SPFA迭代即 ...
- bzoj2595 [Wc2008]游览计划——斯坦纳树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2595 今天刚学了斯坦纳树,还不太会,写一道题练习一下: 参考了博客:http://www.c ...
- 洛谷4294 [WC2008]游览计划——斯坦纳树
题目:https://www.luogu.org/problemnew/show/P4294 大概是状压.两种转移,一个是以同一个点为中心,S由自己的子集拼起来:一个是S相同.中心不同的同层转移. 注 ...
- 【BZOJ-2595】游览计划 斯坦纳树
2595: [Wc2008]游览计划 Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 1518 Solved: 7 ...
- bzoj2595 / P4294 [WC2008]游览计划
P4294 [WC2008]游览计划 斯坦纳树 斯坦纳树,是一种神奇的树.它支持在一个连通图上求包含若干个选定点的最小生成树. 前置算法:spfa+状压dp+dfs(大雾) 我们设$f[o][P]$为 ...
随机推荐
- freeRTOS学习8-21
不能再中断服务程序调用该函数 应该调用xQueueSendFromISR()
- createjs小游戏开发总结
createjs缩放,html组件input的缩放,transform位置,缩放,字体的大小. 移动端横屏和竖屏幕旋转屏幕自适应,input弹出软键盘的原理和位置偏移,focus,blur弹出软键盘. ...
- 修改Jupyter Notebook默认目录
Jupyter Notebook每次打开都需要先进到相应的文件夹再打开 很不方便 首先进入到Jupyter的安装目录,我的是 D:\Anaconda3\Scripts 然后,输入命令: jupyter ...
- 精通Java中的volatile关键字
在一些开源的框架的源码当中时不时都可以看到volatile这个关键字,最近特意学习一下volatile关键字的使用方法. 很多资料中是这样介绍volatile关键字的: volatile是轻量级的sy ...
- PAT B1016.部分A+B(15)
B1016.部分A+B(15) #include <cstdio> #include <cstring> int calc(long long a, long long da) ...
- 【Python基础】03_Python中的命名和关键字
1.Python中的关键字: ['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', ...
- MVC进阶讲解+小技巧-乱七八糟
开发步骤 1.建立项目 2.建立文件夹 3.建立Controllers 4.生成页面 5.编写Html+Js 6.编写异步请求的Action的方法,返回部分页(用于分页) 7.Js中显示部分页 8.增 ...
- 服务端相关知识学习(二)之Zookeeper可以干什么
Zookeeper主要可以干哪些事情 配置管理,名字服务,提供分布式同步以及集群管理.那这些服务又到底是什么呢?我们为什么需要这样的服务?我们又为什么要使用Zookeeper来实现呢,使用Zookee ...
- warning LNK4076: 无效的增量状态文件“../×××.ilk”;正在非增量链接
VS编译警告:warning LNK4076: 无效的增量状态文件“../×××.ilk”;正在非增量链接 解决方法:删除程序提示的输出目录的×××.ilk,重新编译,即可
- LeetCode 腾讯精选50题--最小栈
题目很简单,实现一个最小栈,能够以线形的时间获取栈中元素的最小值 自己的思路如下: 利用数组,以及两个变量, last用于记录栈顶元素的位置,min用于记录栈中元素的最小值: 每一次push,都比较m ...