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

题意:

分析:

斯坦纳树裸题,有几个需要注意的地方

给出矩阵,不用自己建图,但枚举子集转移时会算两遍,需要减去当前点的权值

方案记录比较麻烦,两边的转移都需要记录,最后dfs找方案会比较容易理解

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
#define N 110
#define LL long long
priority_queue <pair <int,int> >q;
LL map[11][11],dis[1<<10][N];
int chosex[1<<10][N],chosey[1<<10][N];
bool change[1<<10][N];
int flg[11][11];
int n,m;
int tx[]={1,-1,0,0};
int ty[]={0,0,1,-1};
int id[N][N],a[N],xx[N],yy[N],cnt,vis[1<<10][N];
void dfs(int sta,int p){
if(!dis[sta][p])return ;
flg[xx[p]][yy[p]]=1;
if(change[sta][p]){
dfs(chosex[sta][p],p);
dfs(chosey[sta][p],p);
}else dfs(sta,id[chosex[sta][p]][chosey[sta][p]]);
}
int main(){
scanf("%d%d",&n,&m);
int i,j,tot=0,k,x;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%lld",&map[i][j]);
id[i][j]=++tot;
xx[tot]=i;yy[tot]=j;
if(!map[i][j]){
a[++cnt]=tot;
}
}
}
int mask=(1<<cnt)-1;
memset(dis,0x3f,sizeof(dis));
for(i=1;i<=cnt;i++){
dis[1<<i-1][a[i]]=0;
}
for(j=1;j<=mask;j++){
for(i=1;i<=n*m;i++){
for(k=j&(j-1);k;k=j&(k-1)){
if(dis[j][i]>dis[k][i]+dis[j-k][i]-map[xx[i]][yy[i]]){
dis[j][i]=dis[k][i]+dis[j-k][i]-map[xx[i]][yy[i]];
chosex[j][i]=k,chosey[j][i]=j-k;
change[j][i]=1;
}
// dis[j][i]=min(dis[j][i],dis[k][i]+dis[j-k][i]-map[xx[i]][yy[i]]);
}
}
for(i=1;i<=n*m;i++){
q.push(make_pair(-dis[j][i],i));
}
while(!q.empty()){
x=q.top().second;q.pop();
if(vis[j][x])continue;
vis[j][x]=1;
int nx=xx[x],ny=yy[x];
for(i=0;i<4;i++){
int dx=nx+tx[i],dy=ny+ty[i];
if(dx>=1&&dx<=n&&dy>=1&&dy<=m){
if(dis[j][id[dx][dy]]>dis[j][x]+map[dx][dy]){
dis[j][id[dx][dy]]=dis[j][x]+map[dx][dy];
chosex[j][id[dx][dy]]=nx;
chosey[j][id[dx][dy]]=ny;
change[j][id[dx][dy]]=0;
q.push(make_pair(-dis[j][id[dx][dy]],id[dx][dy]));
}
}
}
}
}
LL ans=1ll<<60;
int end;
for(i=1;i<=n*m;i++){
if(ans>dis[mask][i]){
ans=dis[mask][i];
end=i;
}
// ans=min(ans,dis[mask][i]);
}
dfs(mask,end);
printf("%lld\n",ans);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(!map[i][j]){
printf("x");
}else if(flg[i][j]){
printf("o");
}else printf("_");
}
puts("");
}
}

BZOJ_2595_[Wc2008]游览计划_斯坦纳树的更多相关文章

  1. 【BZOJ2595_洛谷4294】[WC2008]游览计划(斯坦纳树_状压DP)

    上个月写的题qwq--突然想写篇博客 题目: 洛谷4294 分析: 斯坦纳树模板题. 简单来说,斯坦纳树问题就是给定一张有边权(或点权)的无向图,要求选若干条边使图中一些选定的点连通(可以经过其他点) ...

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

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

  3. bzoj 2595 [Wc2008]游览计划(斯坦纳树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2595 [题意] 给定N*M的长方形,选最少权值和的格子使得要求的K个点连通. [科普] ...

  4. BZOJ2595 WC2008游览计划(斯坦纳树)

    斯坦纳树板子题. 考虑状压dp,设f[i][j][S]表示当前在点(i,j)考虑转移,其所在的联通块包含的关键点集(至少)为S的答案. 转移时首先枚举子集,有f[i][j][S]=min{f[i][j ...

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

    [Luogu4294] 题解 : 斯坦纳树 \(dp[i][j]\) 表示以\(i\)号节点为根,当前状态为\(j\)(与\(i\)连通的点为\(1\)) 当根\(i\)不改变时状态转移方程是: \( ...

  6. BZOJ.2595.[WC2008]游览计划(DP 斯坦纳树)

    题目链接 f[i][s]表示以i为根节点,当前关键点的连通状态为s(每个点是否已与i连通)时的最优解.i是枚举得到的根节点,有了根节点就容易DP了. 那么i为根节点时,其状态s的更新为 \(f[i][ ...

  7. [WC2008]游览计划 「斯坦那树模板」

    斯坦那树 百度释义 斯坦纳树问题是组合优化问题,与最小生成树相似,是最短网络的一种.最小生成树是在给定的点集和边中寻求最短网络使所有点连通.而最小斯坦纳树允许在给定点外增加额外的点,使生成的最短网络开 ...

  8. BZOJ_4006_[JLOI2015]管道连接_斯坦纳树

    BZOJ_4006_[JLOI2015]管道连接_斯坦纳树 题意: 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰. 该部门有 n 个情报站,用 1 到 n 的整数编号.给出 m ...

  9. WC 2008 观光计划(斯坦纳树)

    题意 https://www.lydsy.com/JudgeOnline/problem.php?id=2595 思路 是一道比较裸的斯坦纳树呢- 题意等价于选出包含一些点的最小生成树,这就是斯坦纳树 ...

随机推荐

  1. CRM客户关系管理系统(十二)

    十二章.学员报名流程开发 2  12.1.学员报名合同和证件信息上传 功能: 必须勾选报名合同协议 必须上传个人证件信息 最多只能上传三个文件 文件大小2M以内 列出已上传文件 (1)crm/urls ...

  2. Linux服务器安全审计工具与流程完全指南

    http://Linux.chinaitlab.com/server/860516.html 当今许多linux服务器都不是刚刚部署完毕的新机器,有专业的Linux系统管理员进行定期维护,IT技术人员 ...

  3. python3学习笔记3---引用http://python3-cookbook.readthedocs.io/zh_CN/latest/

    2018-03-01数据结构和算法(3) 1.11 命名切片 假定你有一段代码要从一个记录字符串中几个固定位置提取出特定的数据字段(比如文件或类似格式): ###### 012345678901234 ...

  4. log4j配置及使用

    一.使用方法: 1.将log4j.properties放到你创建项目的src中 2.引入log4j.jar import org.apache.log4j.*; public class log4jT ...

  5. Java多线程:线程间通信之Lock

    Java 5 之后,Java在内置关键字sychronized的基础上又增加了一个新的处理锁的方式,Lock类. 由于在Java线程间通信:volatile与sychronized中,我们已经详细的了 ...

  6. mysql数据库的安装步骤

    Redhat6.5 1.准备工作 卸载使用rpm包安装的mysql-server.mysql软件包 安装自带的ncurses-devel包 rpm -ivh /mnt/Packages/ncurses ...

  7. c语言中realloc()函数解析

    一.基本特性 1. realloc()函数可以重用或扩展以前用malloc().calloc()及realloc()函数自身分配的内存. 2. realloc()函数需两个参数:一个是包含地址的指针( ...

  8. Java(五、类和对象中的例题)

    一.方法中的参数为数值型的(int) import java.util.Scanner; public class ScoreCalc { public void calc(int num1,int ...

  9. Python和Java的硬盘夜话

    这是一个程序员的电脑硬盘,在一个叫做"学习"的目录下曾经生活着两个小程序,一个叫做Hello.java,即Java小子:另外一个叫做hello.c ,也就是C老头儿. C老头儿的命 ...

  10. javascript中!=、!==、==、===操作符总结

    JavaScript 有两种比较方式:严格比较运算符和转换类型比较运算符. 在相等运算符中对应 === .!==和 ==.!=. 先举个栗子 var str = '1' var num0 = 0 va ...