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. Spring Boot 添加jersey-mvc-freemarker依赖后内置tomcat启动不了解决方案

    我在我的Spring Boot 项目的pom.xml中添加了jersey-mvc-freemarker依赖后,内置tomcat启动不了. 报错信息如下: org.springframework.con ...

  2. Spring Boot Kafka

    1.创建集群 http://kafka.apache.org/documentation/#quickstart 有一句我觉得特别重要: For Kafka, a single broker is j ...

  3. AngularJS学习笔记之directive——scope选项与绑定策略

    开门见山地说,scope:{}使指令与外界隔离开来,使其模板(template)处于non-inheriting(无继承)的状态,当然除非你在其中使用了transclude嵌入,这点之后的笔记会再详细 ...

  4. MacOS软件默认安装路径

    缘起 在用苹果电脑后,很多软件安装后并不只是简单的将所有的文件都放到/Applications目录里,尤其是一些开发用的软件.这就导致要修改一些软件的配置很不方便,总是需要各种查找.为了防止以后忘记这 ...

  5. Android框架之Volley与Glide

    PS:在看到这个题目的同时,你们估计会想,Volley与Glide怎么拿来一块说呢,他们虽然不是一个框架,但有着相同功能,那就是图片处理方面.首先我们先来看一下什么volley,又什么是glide. ...

  6. JavaScript数组中出现的次数最多的元素

    var arr = [1,-1,2,4,5,5,6,7,5,8,6]; var maxVal = arr[0]; // 数组中的最大值 var minVal = arr[0]; // 数组中的最小值 ...

  7. java中Collections.sort()方法实现集合排序

    1.Integer/String泛型的List进行排序 List <Integer> integerlist = new ArrayList<Integer>();   //定 ...

  8. sql server 多行数据合并成一列

    首先是源数据: ),cip.CheckIn_StartTime, )),cip.CheckIn_EndTime, )),cip.Rental_Price)) as content from Check ...

  9. Node笔记五-进程、线程

    进程 -每一个正在运行的应用程序都称之为进程 -每一个应用程序都至少有一个进程 -进程是用来给应用程序提供一个运行的环境 -进程是操作系统为应用程序分配资源的一个单位线程 -用来执行应用程序中的代码 ...

  10. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 使用FairyGUI (一)

    我们的热更新脚本在实际使用中,当然也要支持常用的第三方组件,例如这里介绍一个非常实用的第三方UI库:FairyGUI. 什么是FairyGUI 这里照搬FaiyGUI官网的介绍: 重新定义 UI 制作 ...