题意:见题面(我发现自己真是越来越懒了)

有N*M的矩阵,每个格子有一个值a[i,j]

现要求将其中的K个点(称为关键点)用格子连接起来,取(i,j)的费用就是a[i,j]

求K点全部连通的最小花费以及方案

n,m,k<=10

思路:斯坦纳树

虽然去年就疑似过了一道裸题,不过估计也是COPY的std,早就忘干净了

先%了一发论文,看到了几道有意思的SPFA的应用,准备去做一下

dp[i,j,sta]表示以(i,j)为根,关键点联通情况为sta的最小花费

显然初始化 \[ dp[i,j,1<<(k-1)]=0 (i,j为k号关键点)\]

\[ dp[i,j,sta]=dp[i,j,x]+dp[i,j,sta xor x]-a[i,j] \] 即合并子集

\[ dp[i,j,sta]=dp[x,y,sta]+a[i,j]\]  即合并道路

第一个转移可以枚举子集

第二个转移可能有环且形式是最短路,使用SPFA队列更新

类似一个分层图,SPFA的时候只用跑本层的内容

以下转自某大神blog:进行spfa的时候只需要对当前层的节点进行spfa就行了,不需要整个图完全松弛一遍,因为更高的层都可以通过枚举子集而变成若干个更低的层

时间复杂度:SPFA显然O(2^k)

枚举子集的dp时每个点有3个状态:不是子集,是子集但没取到,是子集且枚举到了

所以O(3^k)

总时间复杂度O(3^k*n*m)

PS:其实暴力的想法:Sigma C(k,k-i)*2^i用二项式展开就是3^k啦(感谢邻桌数学国家队CWY同学)

 const oo=;
dx:array[..]of longint=(-,,,);
dy:array[..]of longint=(,,-,);
var dp:array[..,..,..]of longint;
pre:array[..,..,..,..]of longint;
flag,a,inq:array[..,..]of longint;
q:array[..,..]of longint;
n,m,i,j,x,y,k,v,k1,t,w,sta,tmp,ux,uy:longint; procedure dfs(i,j,sta:longint);
var x,y,z:longint;
begin
if sta= then exit;
flag[i,j]:=;
x:=pre[i,j,sta,]; y:=pre[i,j,sta,]; z:=pre[i,j,sta,];
dfs(x,y,z);
if (x=i)and(y=j) then dfs(x,y,sta xor z);
end; procedure print(x,y:longint);
var i,j:longint;
begin
writeln(dp[x,y,(<<k1)-]);
fillchar(flag,sizeof(flag),);
dfs(x,y,(<<k1)-);
for i:= to n do
begin
for j:= to m do
if a[i,j]> then
begin
if flag[i,j]= then write('o')
else write('_');
end
else write('x');
writeln;
end;
end; begin
assign(input,'bzoj2595.in'); reset(input);
assign(output,'bzoj2595.out'); rewrite(output);
readln(n,m);
for i:= to n do
for j:= to m do read(a[i,j]);
fillchar(dp,sizeof(dp),$7f);
for i:= to n do
for j:= to m do
if a[i,j]= then
begin
inc(k1); dp[i,j,<<(k1-)]:=;
end;
for v:= to (<<k1)- do
begin
fillchar(inq,sizeof(inq),);
t:=; w:=;
for i:= to n do
for j:= to m do
begin
x:=v and (v-);
while x> do
begin
tmp:=dp[i,j,x]+dp[i,j,v xor x]-a[i,j];
if tmp<dp[i,j,v] then
begin
dp[i,j,v]:=tmp;
pre[i,j,v,]:=i; pre[i,j,v,]:=j; pre[i,j,v,]:=x;
end;
x:=v and (x-);
end;
if dp[i,j,v]<oo then begin inc(w); q[w,]:=i; q[w,]:=j; inq[i,j]:=; end;
end;
while t<w do
begin
inc(t); ux:=q[t mod ,]; uy:=q[t mod ,]; inq[ux,uy]:=;
for k:= to do
begin
x:=ux+dx[k]; y:=uy+dy[k];
if (x>)and(x<=n)and(y>)and(y<=m)and(dp[ux,uy,v]+a[x,y]<dp[x,y,v]) then
begin
dp[x,y,v]:=dp[ux,uy,v]+a[x,y];
pre[x,y,v,]:=ux; pre[x,y,v,]:=uy; pre[x,y,v,]:=v;
if inq[x,y]= then
begin
inc(w); q[w mod ,]:=x; q[w mod ,]:=y; inq[x,y]:=;
end;
end;
end;
end;
end; for i:= to n do
begin
for j:= to m do
if a[i,j]= then begin print(i,j); break; end;
if a[i,j]= then break;
end;
close(input);
close(output);
end.

【BZOJ2595】游览计划(状压DP,斯坦纳树)的更多相关文章

  1. luogu4294 [WC2008]游览计划(状压DP/斯坦纳树)

    link 题目大意:给定一个网格图,有些点是关键点,选择格点有代价,求把所有关键点联通的最小代价 斯坦纳树模板题 斯坦纳树问题:给定一个图结构,有一些点是关键点,求把这些关键点联通的最小代价e 斯坦纳 ...

  2. [BZOJ4006][JLOI2015]管道连接 状压dp+斯坦纳树

    4006: [JLOI2015]管道连接 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1020  Solved: 552[Submit][Statu ...

  3. [WC2008]游览计划 状压DP,斯坦纳树

    ---题面--- 题解: 这是一道斯坦纳树的题,用状压+spfa来解决 什么是斯坦纳树? 一开始还以为是数据结构来着,其实跟最小生成树很像,大致就是最小生成树只能在各个点之间直接相连,而斯坦纳树则允许 ...

  4. [WC2008]游览计划(状压dp)

    题面太鬼畜不粘了. 题意就是给一张n*m的网格图,每个点有点权,有k个关键点,让你把这k个关键点连成一个联通快的最小代价. 题解 这题nmk都非常小,解法肯定是状压,比较一般的解法插头dp,但不太好写 ...

  5. [bzoj2595][WC2008]游览计划/[bzoj5180][Baltic2016]Cities_斯坦纳树

    游览计划 bzoj-2595 wc-2008 题目大意:题目链接.题目连接. 注释:略. 想法:裸题求斯坦纳树. 斯坦纳树有两种转移方式,设$f[s][i]$表示联通状态为$s$,以$i$为根的最小代 ...

  6. 动态规划:状压DP-斯坦纳树

    最小生成树是最小斯坦纳树的一种特殊情况 最小生成树是在给定的点集和边中寻求最短网络使所有点连通 而最小斯坦纳树允许在给定点外增加额外的点,使生成的最短网络开销最小 BZOJ2595 题意是给定一个棋盘 ...

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

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

  8. 【状压dp】Trie 树 @中山纪念中学20170304

    目录 Trie 树 PROBLEM 题目描述 输入 输出 样例输入 样例输出 SOLUTION CODE Trie 树 PROBLEM 题目描述 字母(Trie)树是一个表示一个字符串集合中所有字符串 ...

  9. HDU.3311.Dig The Wells(DP 斯坦纳树)

    题目链接 \(Description\) 有n座庙.一共n+m个点,可以在任意一些点修建水井,不同位置花费不同:也可以某些点之间连无向边共享水.求使n座庙都有水的最小花费. \(Solution\) ...

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

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

随机推荐

  1. Spring概况

    1. Spring是什么 Spring是一个开源框架,为了解决企业应用开发的复杂性而创建的,但现在已经不止于企业应用. 是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架. ——从大小与开 ...

  2. C语言编程心得

    记录这些是为了日后自己想查阅以前经验的方便,同时若能给其他网友带来一些帮助,就更好了~ C语言,自己经常遇到的问题: 1.段错误 段错误一般是由于访问了不存在的地址造成的,具体的原因有文件路径不存在, ...

  3. Hello Dojo!(翻译)

    http://dojotoolkit.org/documentation/tutorials/1.10/hello_dojo/index.html 欢迎学习DOJO!在本教程中,你将学些到如何加载DO ...

  4. Linux-第一天

    1.etc 配置目录 2.swap 3.挂载点 建立一个目录,作为一个设备的访问入口,光盘镜像文件.移动硬盘.U盘以及Windows网络共享和UNIX NFS网络共享等 mnt目录, 建立挂载点:mn ...

  5. 有关项目上潜在需要的移动端GIS系统源码整理,待后续更新

    GPS Tools For Android 前言: GPS数据在做GIS开发时的一份宝贵的数据,在不侵犯他人隐私的情况下通过互联网的模式收集GPS是成本最为低廉的一种模式. 背景: 现在公司在做一个项 ...

  6. IOS启动页设置适应ios8/9

    直接上截图 1. 添加对应尺寸的图 2.设置三项 3.去掉默认设置 4.特别的xcode 7 需 通过在p.list配置文件中增加节点: Launch image 类型为String 设置值为Defa ...

  7. phonegap(cordova)环境配置

    首先要配置好  java jdk 和 java jre 环境 配置之后 控制台  javac -version 查看是否配置成功 然后配置 Android sdk 配置之后 控制台 输入 adb 查看 ...

  8. Json操作(DynamicJson)

    Json的简介 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了 ...

  9. 【转】抛弃EF,20分构建一个属于自己的ORM框架

    链接:http://www.cnblogs.com/irenebbkiss/p/4157364.html

  10. 分享一下自己正在使用的sublime text里的插件

    真的回头想想要不是当时一个学姐给我介绍了这个编辑器,我可能还是那种迫不得已了不得不编程了才会去敲代码的,可能还是一只不喜欢编程的程序员.可是自从用了这款编辑器,我的世界仿佛都被改变了.天呐,整天忍不住 ...