bzoj3205
和bzoj2595类似,也是斯坦纳树
设f[l,r,]表示在点i机器人组合成了l-r最少推的次数,然后可得
f[l,r,i]=min(f[l,m,i]+f[m+1,r,i])
f[l,r,i]=min(f[l,r,j]+1) 点j能推到i
但是这样做肯定会TLE,考虑两个优化
首先,一开始其实有很多根本用不到,我们可以先从机器人初始位置搜下去,找到所有可以访问的点做dp即可
其次,观察第二个方程,它的边权都是1,我们一定要用spfa转移吗?不,我们可以用直接宽搜
具体的我们维护两个队列,第一个队列是初始的按从小到大排,新加入的点放在第二个队列,每次取两个队头小的那一个
但我还是tle,求神犇指教
const dx:array[..] of longint=(,,,-);
dy:array[..] of longint=(,,-,);
inf=;
type node=record
x,y:longint;
end; var w:array[..] of node;
q1,q2,st:array[..] of longint;
po:array[..,..,..] of longint;
f:array[..,..,..] of longint;
c:array[..,..] of char;
v:array[..] of boolean;
loc:array[..] of longint;
next:array[..,..] of longint;
s:array[..] of longint;
mid,h1,t1,i,j,p,q,l,x,y,k,n,m,ans,mx,tot:longint; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; function dfs(x,y,k:longint):longint;
var xx,yy:longint;
begin
if (po[x,y,k]=) then exit(-);
if po[x,y,k]> then exit(po[x,y,k]);
po[x,y,k]:=;
xx:=x+dx[k];
yy:=y+dy[k];
if (xx<) or (xx>n) or (yy<) or (yy>m) or (c[xx,yy]='x') then po[x,y,k]:=(x-)*m+y
else if c[xx,yy]='A' then po[x,y,k]:=dfs(xx,yy,(k+) mod +)
else if c[xx,yy]='C' then po[x,y,k]:=dfs(xx,yy,k mod +)
else po[x,y,k]:=dfs(xx,yy,k);
exit(po[x,y,k]);
end; function cmp(i,j,l,r:longint):boolean;
begin
exit(f[i,l,r]<f[j,l,r]);
end; procedure sort(l,r:longint);
var i:longint;
begin
for i:= to mx do
inc(s[i],s[i-]);
for i:=t1 downto do
begin
q1[s[f[st[i],l,r]]]:=st[i];
dec(s[f[st[i],l,r]]);
end;
end; procedure bfs(l,r:longint);
var h2,t2,i,x,y:longint;
begin
h2:=;
t2:=;
while (h2<=t2) or (h1<=t1) do
begin
if (h2>t2) or (h1<=t1) and cmp(q1[h1],q2[h2],l,r) then
begin
x:=q1[h1];
inc(h1);
end
else begin
x:=q2[h2];
inc(h2);
end;
v[x]:=true;
for i:= to do
begin
if next[x,i]= then continue;
y:=next[x,i];
if not v[y] and (f[x,l,r]+<f[y,l,r]) then
begin
v[y]:=true;
f[y,l,r]:=f[x,l,r]+;
inc(t2);
q2[t2]:=y;
end;
end;
end;
end; begin
readln(k,m,n);
for i:= to n*m do
for p:= to k do
for q:= to k do
f[i,p,q]:=inf;
for i:= to n do
begin
for j:= to m do
begin
read(c[i,j]);
if (c[i,j]>='') and (c[i,j]<='') then
begin
x:=ord(c[i,j])-;
inc(t1);
w[t1].x:=i; w[t1].y:=j;
f[t1,x,x]:=;
loc[(i-)*m+j]:=t1;
end;
end;
readln;
end;
fillchar(po,sizeof(po),);
h1:=;
while h1<=t1 do
begin
x:=w[h1].x; y:=w[h1].y;
for i:= to do
begin
if po[x,y,i]=- then
begin
po[x,y,i]:=dfs(x,y,i);
if (po[x,y,i]>) and (loc[po[x,y,i]]=) then
begin
inc(t1);
w[t1].x:=(po[x,y,i]-) div m+;
w[t1].y:=(po[x,y,i]-) mod m+;
loc[po[x,y,i]]:=t1;
end;
end;
if po[x,y,i]> then next[h1,i]:=loc[po[x,y,i]];
end;
inc(h1);
end;
tot:=t1;
for l:= to k do
for p:= to k-l+ do
begin
q:=p+l-;
h1:=; t1:=; mx:=;
for i:= to tot do
begin
v[i]:=false;
for mid:=p to q- do
f[i,p,q]:=min(f[i,p,q],f[i,p,mid]+f[i,mid+,q]);
if f[i,p,q]<inf then
begin
inc(t1);
st[t1]:=i;
inc(s[f[i,p,q]]);
if f[i,p,q]>mx then mx:=f[i,p,q];
end;
end;
sort(p,q);
for i:= to mx do
s[i]:=;
bfs(p,q);
end;
ans:=inf;
for i:= to tot do
ans:=min(ans,f[i,,k]);
if ans>=inf then writeln(-)
else writeln(ans);
end.
bzoj3205的更多相关文章
- [BZOJ3205][APIO2013]Robot(斯坦纳树)
3205: [Apio2013]机器人 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 1007 Solved: 240[Submit][Status ...
- bzoj千题计划230:bzoj3205: [Apio2013]机器人
http://www.lydsy.com/JudgeOnline/problem.php?id=3205 历时一天,老子终于把它A了 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 因为不懂spfa ...
- bzoj3205 [Apio2013]机器人
3205: [Apio2013]机器人 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 953 Solved: 227[Submit][Status] ...
- BZOJ3205/UOJ107 [Apio2013]机器人
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- [Bzoj3205][Apio2013]机器人(斯坦纳树)(bfs)
3205: [Apio2013]机器人 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 977 Solved: 230[Submit][Status] ...
- PKUSC2018训练日程(4.18~5.30)
(总计:共66题) 4.18~4.25:19题 4.26~5.2:17题 5.3~5.9: 6题 5.10~5.16: 6题 5.17~5.23: 9题 5.24~5.30: 9题 4.18 [BZO ...
随机推荐
- canvas 的学习
canvas 绘制直线的API有: 1.moveTo()起点坐标. 2.lineTo()绘制的直线 3. fillStyle以及 flii()是绘制实体的 4. strokeStyle 和stroke ...
- A3992学习记录
ATmega64+A3992驱动步进电机 //ATmega 64a 电机驱动板程序//编译环境 AVR Studio 4.17/AVR GCC//系统外部时钟16M//作者:虞恺 //日期:2012. ...
- General Palindromic Number (进制)
A number that will be the same when it is written forwards or backwards is known as a Palindromic Nu ...
- crtmpserver的安装,摄像头视频测试
下载 svn co --username anonymous --password "" https://svn.rtmpd.com/crtmpserver/branches/1. ...
- 元素属性和js数组
arrObj.push(数组元素) --增加arrObj.splice(index,howmany)--删除 一般howmany为1, index,开始截取掉的位置,arrObj[index].P ...
- (转)Linux 文件系统:procfs, sysfs, debugfs 用法简介
网址:http://www.tinylab.org/show-the-usage-of-procfs-sysfs-debugfs/ 1 前言 内核中有三个常用的伪文件系统:procfs,debugfs ...
- Contest2037 - CSU Monthly 2013 Oct (problem A :Small change)
[题解]:二进制拆分 任意一个整数都可以拆分成 2^0 + 2^1 + 2^2 + 2^3 + ....+ m [code]: #include <iostream> #include & ...
- [转载]C#对象序列化与反序列化
文章写的实在是太好了,忍不住转来: http://www.cnblogs.com/LiZhiW/p/3622365.html#_Toc8478 1.对象序列化的介绍 (1).NET支持对象序列化的几种 ...
- linux网络环境配置
第一种方法: (red hat) (1)用root身份登录,运行setup命令进入到text mode setup utility 对网络进行配置,这里可以进行ip,子网掩码,默认网关,dns的设置. ...
- Java发送post请求
package com.baoxiu.test; import java.io.BufferedReader;import java.io.InputStreamReader;import java. ...