斯坦纳树(我也不知道为什么叫这个名字)是一种状压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. go liteIDE 快捷键

    Goland常用快捷键文件相关快捷键: CTRL+E,打开最近浏览过的文件.CTRL+SHIFT+E,打开最近更改的文件.CTRL+N,可以快速打开struct结构体.CTRL+SHIFT+N,可以快 ...

  2. 空间数据索引RTree(R树)完全解析及Java实现

    第一部分 空间数据的背景介绍 空间数据的建模 基于实体的模型(基于对象)Entity-based models (or object based) 常用的空间数据查询方式 空间数据获取的方法 R树 简 ...

  3. 记redis一次Could not get a resource from the pool 异常的解决过程

    最近有个项目中的redis每天都会报 "Could not get a resource from the pool"的错误,而这套代码在另一地方部署又没有问题.一直找不到错误原因 ...

  4. centos7 设置 查看 开机 启动项

    1.查看开机自启项centos7自启项已不用chkconfig改为:systemctl list-unit-files左边是服务名称,右边是状态,enabled是开机启动,disabled是开机不启动 ...

  5. Ubuntu安装usb库

    sudo pip install pyserial sudo pip install pyusb

  6. grant_type为client_credentials和password二者的区别

    最近工作中需要使用到oauth,注意到oauth客户端的grant_type值可以指定为client_credentials和password两种,很好奇所以网上搜索了一下,发现stackoverfl ...

  7. unity获取ugui上鼠标位置

    public class GetMousePos : MonoBehaviour { public Canvas canvas;//画布 private RectTransform rectTrans ...

  8. ubuntu-网络配置文件

    vim   /etc/NetworkManager/system-connections/Wired connectione 1 

  9. python面试总结4(算法与内置数据结构)

    算法与内置数据结构 常用算法和数据结构 sorted dict/list/set/tuple 分析时间/空间复杂度 实现常见数据结构和算法 数据结构/算法 语言内置 内置库 线性结构 list(列表) ...

  10. vue-cli3.0 脚手架搭建项目的过程详解

    1.安装vue-cli 3.0 ? 1 2 3 npm install -g @vue/cli # or yarn global add @vue/cli 安装成功后查看版本:vue -V(大写的V) ...