斯坦纳树板子题。

  考虑状压dp,设f[i][j][S]表示当前在点(i,j)考虑转移,其所在的联通块包含的关键点集(至少)为S的答案。

  转移时首先枚举子集,有f[i][j][S]=min{f[i][j][x]+f[i][j][y]-a[i][j]} (x&y=0,x|y=S)。

  然后考虑从点(i,j)从哪拓展而来,有f[i][j][S]=min{f[x][y][S]}+a[i][j],其中(x,y)为(i,j)的相邻点,使用spfa转移。

  这里第二种转移仅在相同关键点集下进行,因为由更小点集转移而来的情况已在第一种转移中被考虑。

  对于输出方案,记录如何转移而来即可。

  其实并没有搞懂。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 12
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,s,a[N][N],id[N][N],f[N][N][<<N],from[N][N][<<N][],q[N*N*N*N][];
int wx[]={,,,-},wy[]={,,-,};
bool flag[N][N];
char b[N][N];
void inc(int &x){x++;if (x>n*m+) x-=n*m+;}
void spfa(int k)
{
int head=,tail=;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
tail++,q[tail][]=i,q[tail][]=j,flag[i][j]=;
do
{
inc(head);int x=q[head][],y=q[head][];flag[x][y]=;
for (int i=;i<;i++)
{
int u=x+wx[i],v=y+wy[i];
if (u&&u<=n&&v&&v<=m&&f[x][y][k]+a[u][v]<f[u][v][k])
{
f[u][v][k]=f[x][y][k]+a[u][v];
from[u][v][k][]=x,from[u][v][k][]=y;
if (!flag[u][v]) flag[u][v]=,inc(tail),q[tail][]=u,q[tail][]=v;
}
}
}while (head!=tail);
}
void getans(int x,int y,int k)
{
b[x][y]='o';
while (from[x][y][k][]>)
{
int u=from[x][y][k][],v=from[x][y][k][];
b[x=u][y=v]='o';
}
if (from[x][y][k][]<) getans(x,y,-from[x][y][k][]),getans(x,y,-from[x][y][k][]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj2595.in","r",stdin);
freopen("bzoj2595.out","w",stdout);
#endif
n=read(),m=read();
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
a[i][j]=read(),s+=(a[i][j]==);
if (!a[i][j]) id[i][j]=s;
}
memset(f,,sizeof(f));
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
f[i][j][]=a[i][j];
if (id[i][j]) f[i][j][<<id[i][j]-]=a[i][j];
}
for (int k=;k<(<<s);k++)
{
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
for (int x=k;x>=(k^x);x=x-&k)
if (f[i][j][x]+f[i][j][k^x]-a[i][j]<f[i][j][k])
{
f[i][j][k]=f[i][j][x]+f[i][j][k^x]-a[i][j];
from[i][j][k][]=-x,from[i][j][k][]=-(k^x);
}
spfa(k);
}
int ans=;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
ans=min(ans,f[i][j][(<<s)-]);
cout<<ans<<endl;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
b[i][j]='_';
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (f[i][j][(<<s)-]==ans)
{
getans(i,j,(<<s)-);
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (!a[i][j]) b[i][j]='x';
for (int i=;i<=n;i++)
{
for (int j=;j<=m;j++)
putchar(b[i][j]);
cout<<endl;
}
return ;
}
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. [拍摄]『ROSE 拆解』SONY 摄像机镜头拆解。

    镜头是从一部很老的sony摄像机上拆下来的.具体型号记不清了.应该是DCR系列的某个型号.使用Hi8磁带.NNN年前摄像机因为意外进水报废...拆拆去最后只剩下镜头了.镜头总成. 图片:IMG_201 ...

  2. 基于TDA4863-2的单级PFC反激LED电源设计与仿真

    LED是一个非线性器件,正向电压的微小变化会引起电流的巨大变化:LED是一个半导体二极管,其伏安特性随温度变化而变化(-2mV/℃),假如温度升高,在恒压驱动下LED的电流会增加.长期超过额定电流工作 ...

  3. security相关链接整理

    token令牌 ssl协议 https协议 对称加密与非对称加密 认识ASP.NET Windows身份认证

  4. CF28D Don't fear, DravDe is kind 背包

    题目传送门:http://codeforces.com/problemset/problem/28/D 题意:给你$N$个物品,每个物品有其价格$P_i$,之前必须要买的物品价格和$L_i$,之后必须 ...

  5. eclipse 打包

    add directory entries 不勾选, spring 自动扫描之类的扫描不到

  6. [Oracle]Oracle 各产品的 生命周期

    http://www.oracle.com/us/support/library/lifetime-support-technology-069183.pdf

  7. BodeAbp概述

    BodeAbp框架基于github开源框架ASP.NET Boilerplate,abp项目地址:https://github.com/aspnetboilerplate/aspnetboilerpl ...

  8. 一个很好用的在线编辑、展示、分享、交流JavaScript 代码的平台

    在发表博客时,有一些代码只能粘贴进去,而不能看到代码运行的效果,需要读者把代码粘贴进自己的编辑器,然后再运行看效果,这是一件很耗时的事情 在平时百度的时候,我发现一些网站可以在线预览功能,而且可以在线 ...

  9. Ionic2 下处理 Android 设备下返回按钮的事件

    原文发表于我的技术博客 本文分享了 Ionic2 下处理 Android 设备下返回按钮的事件,供参考. 原文发表于我的技术博客 代码中我分享了如何捕捉 Ionic2 项目在 Android 设备下返 ...

  10. Mysql优化系列(1)--Innodb重要参数优化

    1.简单介绍InnoDB给MySQL提供了具有提交,回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎.InnoDB锁定在行级并且也在SELECT语句提供一个Oracle风格一致的非锁定读.这些特色 ...