斯坦纳树(我也不知道为什么叫这个名字)是一种状压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. iOS - 安装CocoaPods详细过程(重装系统后!)

    重装的系统,发现很多东西都要重装,顺便复习和检验下以前的方法还有没有效 一.简介 什么是CocoaPods CocoaPods是OS X和iOS下的一个第三类库管理工具,通过CocoaPods工具我们 ...

  2. 从 SimpleIntegerProperty 看 Java属性绑定(property binding) 与 观察者模式(Observable)

    //TODO:ExpressionHelper .bindBidirectional双向绑定.以及IntegerExpression的一系列算术方法和返回的IntegerBinding暂未详细解析(比 ...

  3. python day5 lambda,内置函数,文件操作,冒泡排序以及装饰器

    目录 python day 5 1. 匿名函数lambda 2. python的内置函数 3. python文件操作 4. 递归函数 5. 冒泡排序 6. 装饰器 python day 5 2019/ ...

  4. element-ui 穿梭框使用axios数据查询

    //class="input"样式自写,用来覆盖穿梭框自带的搜索,它自带的搜索框不能搜索外部数据,只能查询在穿梭框内的数据 <div style="text-ali ...

  5. 博客使用 utterances 作为评论系统

    utterances 是一款基于 GitHub issues 的评论工具. 相比同类的工具 gitment.gitalk 以及 disqus 评论工具,优点如下: 极其轻量 加载非常快 配置比较简单 ...

  6. 移动oracle数据文件的两种方法

    1.alter database方法该方法,可以移动任何表空间的数据文件. ***关闭数据库***SQL> shutdown immediateDatabase closed.Database ...

  7. Vue中v-model解析、sync修饰符解析

    上善若水,水善利萬物而不爭.——<道德經> 简介 在平时开发是经常用到一些父子组件通信,经常用到props.vuex等等,这里面记录另外的三种方式v-model.sync是怎么使用,再说是 ...

  8. Springboot默认定时任务——Scheduled注解

    1.pom配置 <dependencies> <dependency> <groupId>org.springframework.boot</groupId& ...

  9. 【Linux下Hadoop-eclipse-plus-3.2.0】编译Hadoop连接eclipse的插件遇见的一系列错误,崩溃的操作

    2019-09-02 23:35:22 前言:首先,我想吐槽下自己,居然花费了4到5个夜晚和中午的时间来做这件事情,直到刚才才顺利解决,我也挺佩服自己的! 我在这个过程中参考其他人的博客,非常感谢他们 ...

  10. ORA-01031:insufficient privileges 解决方法

    使用sys或system帐号登录plSql时,提示ORA-01031:insufficient privileges 错误.使用其他的帐号能正常登录,在cmd命令中用system帐号也是可以正常登录. ...