斯坦纳树(我也不知道为什么叫这个名字)是一种状压dp的套路,求在无向带花连通图中,选取边使一些特殊点连通起来的最小花费。

具体到这题就是这样的,设\(f_{u,S}\)表示当前根是\(u\),与它连通的特殊点的集合是\(S\)的最小花费。

首先要合并自身的集合。

\[f_{u,S}=\min_{T\subseteq S}(f_{u,T}+f_{u,S-T}-a_u)
\]

还有换根。

\[f_{u,S}=\min_{(u,v)\in E}(f_{v,S}+a_u)
\]

这个东西可以用spfa来转移。

#include<bits/stdc++.h>
#define Rint register int
#define MP make_pair
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
const int N = 11, M = 103, d[2][4] = {{0, 1, 0, -1}, {1, 0, -1, 0}}, inf = 0x3f3f3f3f;
int n, m, tot, a[N][N], f[N][N][1024], front, rear;
struct Node {
int x, y, S;
} pre[N][N][1024];
pii q[M];
bool inq[N][N];
inline void AMOD(int &x){++ x; if(x == M) x = 0;}
inline void spfa(int S){
while(front != rear){
pii now = q[front]; AMOD(front);
int ox = now.fi, oy = now.se; inq[ox][oy] = false;
for(Rint i = 0;i < 4;i ++){
int nx = ox + d[0][i], ny = oy + d[1][i];
if(nx >= 1 && nx <= n && ny >= 1 && ny <= m && f[nx][ny][S] > f[ox][oy][S] + a[nx][ny]){
f[nx][ny][S] = f[ox][oy][S] + a[nx][ny];
pre[nx][ny][S] = (Node){ox, oy, S};
if(!inq[nx][ny]){inq[nx][ny] = true; q[rear] = MP(nx, ny); AMOD(rear);}
}
}
}
}
bool vis[N][N];
inline void dfs(int x, int y, int S){
vis[x][y] = true;
Node tmp = pre[x][y][S];
if(tmp.x == 0 && tmp.y == 0) return;
dfs(tmp.x, tmp.y, tmp.S);
if(tmp.x == x && tmp.y == y) dfs(tmp.x, tmp.y, S - tmp.S);
}
int main(){
scanf("%d%d", &n, &m);
memset(f, 0x3f, sizeof f);
for(Rint i = 1;i <= n;i ++)
for(Rint j = 1;j <= m;j ++){
scanf("%d", a[i] + j);
if(!a[i][j]) f[i][j][1 << tot] = 0, ++ tot;
}
int lim = 1 << tot;
for(Rint S = 0;S < lim;S ++){
front = rear = 0;
for(Rint i = 1;i <= n;i ++)
for(Rint j = 1;j <= m;j ++){
for(Rint SS = S;SS;SS = (SS - 1) & S)
if(f[i][j][S] > f[i][j][SS] + f[i][j][S - SS] - a[i][j]){
f[i][j][S] = f[i][j][SS] + f[i][j][S - SS] - a[i][j];
pre[i][j][S] = (Node){i, j, SS};
}
if(f[i][j][S] < inf) q[rear ++] = MP(i, j), inq[i][j] = true;
}
spfa(S);
}
int ansx = 0, ansy = 0;
bool flag = true;
for(Rint i = 1;flag && i <= n;i ++)
for(Rint j = 1;flag && j <= m;j ++)
if(!a[i][j]){ansx = i; ansy = j; flag = false;}
printf("%d\n", f[ansx][ansy][lim - 1]);
dfs(ansx, ansy, lim - 1);
for(Rint i = 1;i <= n;i ++){
for(Rint j = 1;j <= m;j ++)
if(!a[i][j]) putchar('x');
else if(vis[i][j]) putchar('o');
else putchar('_');
putchar('\n');
}
}

Luogu4294 【WC2008】游览计划的更多相关文章

  1. luogu4294 [WC2008]游览计划(状压DP/斯坦纳树)

    link 题目大意:给定一个网格图,有些点是关键点,选择格点有代价,求把所有关键点联通的最小代价 斯坦纳树模板题 斯坦纳树问题:给定一个图结构,有一些点是关键点,求把这些关键点联通的最小代价e 斯坦纳 ...

  2. BZOJ_2595_[Wc2008]游览计划_斯坦纳树

    BZOJ_2595_[Wc2008]游览计划_斯坦纳树 题意: 分析: 斯坦纳树裸题,有几个需要注意的地方 给出矩阵,不用自己建图,但枚举子集转移时会算两遍,需要减去当前点的权值 方案记录比较麻烦,两 ...

  3. [WC2008]游览计划 解题报告

    [WC2008]游览计划 斯坦纳树板子题,其实就是状压dp 令\(dp_{i,s}\)表示任意点\(i\)联通关键点集合\(s\)的最小代价 然后有转移 \[ dp_{i,S}=\min_{T\in ...

  4. bzoj2595 / P4294 [WC2008]游览计划

    P4294 [WC2008]游览计划 斯坦纳树 斯坦纳树,是一种神奇的树.它支持在一个连通图上求包含若干个选定点的最小生成树. 前置算法:spfa+状压dp+dfs(大雾) 我们设$f[o][P]$为 ...

  5. 【BZOJ2595】 [Wc2008]游览计划

    BZOJ2595 [Wc2008]游览计划 Solution 考虑这是一个最小费用连通性的问题,既然大家都说这是什么斯坦纳树那就是的吧... 所以我们肯定可以这样设一个dp状态: \(dp_{i,j, ...

  6. 【BZOJ2595】[Wc2008]游览计划 斯坦纳树

    [BZOJ2595][Wc2008]游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为 ...

  7. 【LG4294】[WC2008]游览计划

    [LG4294][WC2008]游览计划 题面 洛谷 bzoj 题解 斯坦纳树板子题. 斯坦纳树的总结先留个坑. 代码 #include <iostream> #include <c ...

  8. 【BZOJ 2595】2595: [Wc2008]游览计划 (状压DP+spfa,斯坦纳树?)

    2595: [Wc2008]游览计划 Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 1572  Solved: 7 ...

  9. BZOJ2595 Wc2008 游览计划 【斯坦纳树】【状压DP】*

    BZOJ2595 Wc2008 游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个 ...

  10. [bzoj2595][WC2008]游览计划/[bzoj5180][Baltic2016]Cities_斯坦纳树

    游览计划 bzoj-2595 wc-2008 题目大意:题目链接.题目连接. 注释:略. 想法:裸题求斯坦纳树. 斯坦纳树有两种转移方式,设$f[s][i]$表示联通状态为$s$,以$i$为根的最小代 ...

随机推荐

  1. 深度自适应增量学习(Incremental Learning Through Deep Adaptation)

    深度自适应增量学习(Incremental Learning Through Deep Adaptation) 2018-05-25 18:56:00 木呆呆瓶子 阅读数 10564  收藏 更多 分 ...

  2. helm chart应用使用示例

    有两种方法 一是按照正常流程直接用yaml文件的形式发布应用到k8s集群上 二是把生成好的yaml文件发布到kubeapps应用商店,在应用商店中操作发布应用到k8s集群中 这里采用第二种方式的变种方 ...

  3. 内网Https 自签Https证书 配合Tomcat 实现内网Https详细图文

    内网项目启用Https配置手册 软件需求: OpenSSL https://www.openssl.org/ 已经安装了Java Jdk环境 制作前的需求: 已经配置了Jdk环境变量 安装好OpenS ...

  4. oralce数据表空间满了

    --切换至oralce用户 su - oracle--执行sqlplus / as sysdba --查询表空间使用情况SELECT Upper(F.TABLESPACE_NAME) "表空 ...

  5. .Net Core 注入学习——注册服务

    解析 .Net Core 注入——注册服务发表于:2017-10-23 10:47 作者:行走即歌 来源:51Testing软件测试网采编字体:大 中 小 | 上一篇 | 下一篇 |我要投稿 | 推荐 ...

  6. 并发编程之Java锁

    一.重入锁 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized(重量级) 和 ReentrantLock(轻量级)等等 ) .这些已经写好提供的锁为我们开发提 ...

  7. input中blur失去焦点事件与点击事件冲突时如何解决

    方法一 使用setTimeout $(function(){ $(".cy-name-input input").on({ focus:function() { $(". ...

  8. JavaScript函数参数传递

    Hello,今天和大家分享下JS中的一个基本概念:函数参数传递! 先来看看一个DEMO var str="hello world"; function func(s){ s=&qu ...

  9. 导航条按钮的设置UIBarButtonItem

    1.目的 2.代码 // 设置导航栏的按钮 UIButton *leftNavBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 35, 35 ...

  10. Python——数据类型公用功能

    1.索引 表示从哪里开始取值. 支持类型 str 列表 dict 不支持类型 int bool a= '1234567' print(a[1:])#指从哪开始读取,1为从1号元素开始.默认为0 pri ...