[Luogu4294]

题解 : 斯坦纳树

\(dp[i][j]\) 表示以\(i\)号节点为根,当前状态为\(j\)(与\(i\)连通的点为\(1\))

当根\(i\)不改变时状态转移方程是:

\(dp[i][j] = \min_{s \in j}\{dp[i][s] + dp[i][\complement_js] - val[i]\}\)

当根改变时,要求\(i,k\)相邻 :

\(dp[i][j] = \min\{dp[k][j] + val[i]\}\)

记录\(pre[i][now]\)为由哪个状态转移而来,便于输出方案

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int INF=1e9+7;
inline LL read(){
register LL x=0,f=1;register char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f*x;
} int f[101][1111],a[101],d[4][2]={1,0,0,1,0,-1,-1,0};
bool inq[101],ans[11][11];
pii pre[101][1111];
queue <int> q;
int n,m,K,rt; inline void SPFA(int now){
while(!q.empty()){
int u=q.front();q.pop();inq[u]=0;
for(int i=0;i<4;i++){
int x=u/m,y=u%m,tx=x+d[i][0],ty=y+d[i][1],v=tx*m+ty;
if(tx<0||tx>=n||ty<0||ty>=m) continue;
if(f[u][now]+a[v]<f[v][now]){
f[v][now]=f[u][now]+a[v];
if(!inq[v]) inq[v]=1,q.push(v);
pre[v][now]=pii(u,now);//状态为now定义为与根相连的点的状态,只有相邻的才能转移
}
}
}
} inline void dfs(int x,int y,int now){
int u=x*m+y;
if(!pre[u][now].second) return;
ans[x][y]=1;
if(pre[u][now].first==u) dfs(x,y,now^pre[u][now].second);//如果是由自己更新过来,就要往两个方向回溯
dfs(pre[u][now].first/m,pre[u][now].first%m,pre[u][now].second);//否则就只往一个方向
} int main(){
n=read(),m=read();
memset(f,0x3f,sizeof f);
for(int i=0,now=0;i<n;i++)
for(int j=0;j<m;j++,now++){
a[now]=read();
if(!a[now]) f[now][1<<(K++)]=0,rt=now;
}
for(int now=1;now<(1<<K);now++){
for(int i=0;i<n*m;i++){
for(int s=now&(now-1);s;s=(s-1)&now)
if(f[i][s]+f[i][now^s]-a[i]<f[i][now]){
f[i][now]=f[i][s]+f[i][now^s]-a[i];//用自己的信息更新
pre[i][now]=pii(i,s);
}
if(f[i][now]<f[0][0])
q.push(i),inq[i]=1;
}
SPFA(now);//更新状态为now的全部的值
}
printf("%d\n",f[rt][(1<<K)-1]);
dfs(rt/m,rt%m,(1<<K)-1);
for(int i=0,now=0;i<n;i++){
for(int j=0;j<m;j++,now++){
if(!a[now]) putchar('x');
else putchar(ans[i][j]?'o':'_');
}
putchar('\n');
}
}

[WC2008]游览计划(斯坦纳树)的更多相关文章

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

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

  2. Luogu 4294 [WC2008]游览计划 | 斯坦纳树

    题目链接 Luogu 4294 (我做这道题的时候BZOJ全站的SPJ都炸了 提交秒WA 幸好有洛谷) 题解 这道题是[斯坦纳树]的经典例题.斯坦纳树是这样一类问题:带边权无向图上有几个(一般约10个 ...

  3. bzoj2595: [Wc2008]游览计划 斯坦纳树

    斯坦纳树是在一个图中选取某些特定点使其联通(可以选取额外的点),要求花费最小,最小生成树是斯坦纳树的一种特殊情况 我们用dp[i][j]来表示以i为根,和j状态是否和i联通,那么有 转移方程: dp[ ...

  4. BZOJ2595: [Wc2008]游览计划(斯坦纳树,状压DP)

    Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 2030  Solved: 986[Submit][Status][ ...

  5. BZOJ 2595 [Wc2008]游览计划 ——斯坦纳树

    [题目分析] 斯坦纳树=子集DP+SPFA? 用来学习斯坦纳树的模板. 大概就是用二进制来表示树包含的点,然后用跟几点表示树的形态. 更新分为两种,一种是合并两个子集,一种是换根,换根用SPFA迭代即 ...

  6. bzoj2595 [Wc2008]游览计划——斯坦纳树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2595 今天刚学了斯坦纳树,还不太会,写一道题练习一下: 参考了博客:http://www.c ...

  7. P4294 [WC2008]游览计划 (斯坦纳树)

    题目链接 差不多是斯坦纳树裸题,不过边权化成了点权,这样在合并两棵子树时需要去掉根结点的权值,防止重复. 题目还要求输出解,只要在转移时记录下路径,然后dfs一遍就好了. #include<bi ...

  8. 洛谷4294 [WC2008]游览计划——斯坦纳树

    题目:https://www.luogu.org/problemnew/show/P4294 大概是状压.两种转移,一个是以同一个点为中心,S由自己的子集拼起来:一个是S相同.中心不同的同层转移. 注 ...

  9. 【BZOJ-2595】游览计划 斯坦纳树

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

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

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

随机推荐

  1. 1-3 并发与高并发基本概念.mkv

  2. std:: lower_bound std:: upper_bound

    std:: lower_bound 该函数返回范围内第一个不小于(大于或等于)指定val的值.如果序列中的值都小于val,则返回last.序列应该已经有序! eg: #include <iost ...

  3. weblogic在linux服务器上部署应用

    SSH软件连接服务器: 服务器地址:xxx.xxx.xxx.40 用户名:xxxx 密码:xxxx 新建文件夹,用来放新代码版本,后面为代码版本号 路径:/home/weblogic 命令:mkdir ...

  4. mysql中如何不重复插入满足某些条件的重复的记录的问题

    最近在项目中遇到了这样的一个问题“: 在mysql数据库中需要每次插入的时候不能插入三个字段都相同的记录.在这里使用到了 insert into if not exists  和insert igno ...

  5. 如何从Win7上卸载Sql 2008 R2 Express,再重装

    这两天,因工作需要,需要在一台新的机器上,Win7 64位英文操作系统上,安装Sql Server 2008 R2 Express,安装的过程中出现些问题,在查找问题的过程中,考虑重装 Sql Ser ...

  6. win32多线程 (四) Mutex

    Mutex 用途和critical  section 非常类似,不过Mutex是内核对象,速度比section慢.Mutexes可以跨进程使用.另外Mutex在等待的时候可以设置等待时间. 以下是两种 ...

  7. xml 操作(动态添加 property属性 其他节点同理)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. 【linux命令】setterm控制终端属性命令(中英文)

    [linux命令]setterm控制终端属性命令(中英文) 2018年03月23日 17:13:44 阅读数:489 标签: linux 更多 个人分类: linux 摘自:https://blog. ...

  9. Python基础-5

    目录 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 hashlib re正则表达式 模块 ...

  10. samba服务器共享开发【windows下开发linux网站】

    //@author:yuan<turing_zhy@163.com> //@date:2018-08-05 //注:码字不易转载请注明出处 //环境准备:ubuntu1~16.04.4 1 ...