bzoj2595
一开始看是插头dp,后来发现还有一个叫斯坦纳树的东西
什么叫斯坦纳树,就是使给定点连通开销和最小的树(可以包含多余的点)
到这张平面图上,我们不难想到用dp来解决,设f[x,y,S]表示连通集合为S,树根为点(x,y)的最小开销
不难得到两个方程式
f[x,y,S]=min(f[x,y,s']+f[x,y,S-s']-a[x,y]) S'是S的一个子集,相当于合并两个数
f[x,y,S]=min(f[x',y',S]+a[x,y]) (x',y')与(x,y)相邻
由于景点很少,我们显然可以用状压dp,初始f[景点坐标,景点状态]=0
第一个方程转移大家都会,第二个方程转移是没有明确转移顺序,只要转移起点,因此我们用spfa转移
所以总的处理转移,我们穷举连通状况,然后先用第一个方程转移,然后再用第二个方程转移
const dx:array[..] of longint=(,,,-);
dy:array[..] of longint=(,-,,);
inf=;
type node=record
x,y,k:longint;
end; var q:array[..] of node;
pre:array[..,..,..] of node;
f:array[..,..,..] of longint;
v:array[..,..] of boolean;
a:array[..,..] of longint;
t,h,r,k,i,j,s,n,m,x,y:longint; function make(i,j,k:longint):node;
begin
make.x:=i;
make.y:=j;
make.k:=k;
end; procedure spfa(k:longint);
var i,x,y,x0,y0:longint;
begin
while h<=r do
begin
x0:=q[h].x; y0:=q[h].y;
v[x0,y0]:=false;
for i:= to do
begin
x:=x0+dx[i];
y:=y0+dy[i];
if (x<) or (x>n) or (y<) or (y>m) then continue;
if f[x,y,k]>f[x0,y0,k]+a[x,y] then
begin
f[x,y,k]:=f[x0,y0,k]+a[x,y];
pre[x,y,k]:=make(x0,y0,k);
if not v[x,y] then
begin
v[x,y]:=true;
inc(r);
q[r].x:=x; q[r].y:=y;
end;
end;
end;
inc(h);
end;
end; procedure dfs(x,y,k:longint);
var m:node;
begin
v[x,y]:=true;
m:=pre[x,y,k];
if m.x= then exit;
dfs(m.x,m.y,m.k);
if (m.x=x) and (m.y=y) then dfs(m.x,m.y,k-m.k);
end; begin
readln(n,m);
for i:= to n do
for j:= to m do
for k:= to do
f[i,j,k]:=inf;
for i:= to n do
for j:= to m do
begin
read(a[i,j]);
if a[i,j]= then
begin
f[i,j, shl t]:=;
inc(t);
end;
end;
h:=;
r:=;
for k:= to shl t- do
begin
for i:= to n do
for j:= to m do
begin
s:=k and (k-);
while s<> do //穷举子集
begin
if f[i,j,k]>f[i,j,s]+f[i,j,k-s]-a[i,j] then
begin
f[i,j,k]:=f[i,j,s]+f[i,j,k-s]-a[i,j];
pre[i,j,k]:=make(i,j,s); //记录从哪转移来的
end;
s:=k and (s-);
end;
if f[i,j,k]<inf then
begin
v[i,j]:=true;
inc(r);
q[r].x:=i; q[r].y:=j;
end;
end;
spfa(k);
h:=;
r:=;
end;
for i:= to n do
for j:= to m do
if a[i,j]= then
begin
x:=i;
y:=j;
break;
end; writeln(f[x,y, shl t-]);
dfs(x,y, shl t-);
for i:= to n do
begin
for j:= to m do
if a[i,j]= then write('x')
else if v[i,j] then write('o')
else write('_');
writeln;
end;
end.
bzoj2595的更多相关文章
- 【BZOJ2595】游览计划(状压DP,斯坦纳树)
题意:见题面(我发现自己真是越来越懒了) 有N*M的矩阵,每个格子有一个值a[i,j] 现要求将其中的K个点(称为关键点)用格子连接起来,取(i,j)的费用就是a[i,j] 求K点全部连通的最小花费以 ...
- BZOJ2595 WC2008游览计划(斯坦纳树)
斯坦纳树板子题. 考虑状压dp,设f[i][j][S]表示当前在点(i,j)考虑转移,其所在的联通块包含的关键点集(至少)为S的答案. 转移时首先枚举子集,有f[i][j][S]=min{f[i][j ...
- 【BZOJ2595】 [Wc2008]游览计划
BZOJ2595 [Wc2008]游览计划 Solution 考虑这是一个最小费用连通性的问题,既然大家都说这是什么斯坦纳树那就是的吧... 所以我们肯定可以这样设一个dp状态: \(dp_{i,j, ...
- 【BZOJ2595】[Wc2008]游览计划 斯坦纳树
[BZOJ2595][Wc2008]游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为 ...
- BZOJ2595 [Wc2008]游览计划 【状压dp + 最短路】
题目链接 BZOJ2595 题解 著名的斯坦纳树问题 设\(f[i][j][s]\)表示点\((i,j)\)与景点联通状况为\(s\)的最小志愿者数 设\(val[i][j]\)为\((i,j)\)需 ...
- BZOJ2595 Wc2008 游览计划 【斯坦纳树】【状压DP】*
BZOJ2595 Wc2008 游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个 ...
- [bzoj2595][WC2008]游览计划/[bzoj5180][Baltic2016]Cities_斯坦纳树
游览计划 bzoj-2595 wc-2008 题目大意:题目链接.题目连接. 注释:略. 想法:裸题求斯坦纳树. 斯坦纳树有两种转移方式,设$f[s][i]$表示联通状态为$s$,以$i$为根的最小代 ...
- bzoj2595 [Wc2008]游览计划——斯坦纳树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2595 今天刚学了斯坦纳树,还不太会,写一道题练习一下: 参考了博客:http://www.c ...
- BZOJ2595[WC2008]游览计划
Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点:否则表示控制该方块至少需要的志愿者数 ...
随机推荐
- JSONP 含jquery 实例
前言: 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Soc ...
- php字符串首字母转换大小写的实例分享
php中对字符串首字母进行大小写转换的例子. in: 后端程序首字母变大写:ucwords() <?php $foo = 'hello world!'; $foo = ucwords($foo) ...
- Spark小课堂Week5 Scala初探
Spark小课堂Week5 Scala初探 Scala是java威力加强版. 对Java的改进 这里会结合StreamingContext.scala这个代码说明下对Java的改进方面. 方便测试方式 ...
- [python] 字符串引用
%s str %d 整数 %f 浮点数 print('$%.03f' % 30.1777) >>>$30.178 #四舍五入 print( '%-5s %s %10s' % ('J ...
- Speech Patterns (string)
People often have a preference among synonyms of the same word. For example, some may prefer "t ...
- oracle闪回表详解
--- 说明闪回数据库 --- 使用闪回表将表内容还原到过去的特定时间点 --- 从删除表中进行恢复 --- 使用闪回查询查看截止到任一时间点的数据库内容 --- 使用闪回版本查询查看某一行在一段时间 ...
- C# 白话系列之——白话委托
今天看到首页有个委托的文章,但大都写的太专业,而且没有实用的例子场景.正好昨天做了一个有关委托的功能,所以也来凑个热闹,用白话掰掰 一.委托是什么 我们都知道数据类型,简单点的如,想给一个变量赋值整数 ...
- IOS UIVIEW layer动画 总结(转)
转发自:http://www.aichengxu.com/article/%CF%B5%CD%B3%D3%C5%BB%AF/16306_12.html IOS UIVIEW layer动画 总结, ...
- [SQL SERVER系列]存储过程,游标和触发器实例[原创]
自己写的存储过程与游标结合使用的实例,与大家分享,也供自己查阅,仅供参考: --使用游标循环处理,删除重复的记录 declare @UserID int ) ) declare @UnitFlag i ...
- [转载]Unity3D 访问Access数据库
在开始这个小教程之前呢,其实在网上你已经可以找到相关的资料了,但是我还是要把我自己做练习的一点东西分享出来.写这个教程的主要原因呢,是一个朋友在u3d的官网论坛里,找到了这个demo,但是在他使用的过 ...