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 ...
随机推荐
- javascript学习笔记(5
1.string Array Date Math 内置对象的属性和方法? 答案: ①String 字符串 属性 :length 获取字符串长度 方法: indexOf() 从左到右检索子字符串在原 ...
- PHP中CURL技术模拟登陆抓取网站信息,用与微信公众平台成绩查询
伴随微信的红火,微信公众平台成为许多开发者的下一个目标.笔者本身对于这种新鲜事物没有如此多的吸引力.但是最近有朋友帮忙开发微信公众平台中一个成绩查询的功能.于是便在空余时间研究了一番. 主要的实现步骤 ...
- Spark Streaming揭秘 Day22 架构源码图解
Spark Streaming揭秘 Day22 架构源码图解 今天主要是通过图解的方式,对SparkStreaming的架构进行一下回顾. 下面这个是其官方标准的流程描述. SparkStreamin ...
- Sharing
To store English words, one method is to use linked lists and store a word letter by letter. To save ...
- IOS播放音频 AVAudioPlayer(实例)
1. AVFoundation Build Phases => Link Binary With Libraies => + => AVFoundation.framework =& ...
- 关于count(1) 和 count(*)
Q:What is the difference between count(1) and count(*) in a sql queryeg.select count(1) from emp; an ...
- iOS sqlite数据库实现(转)
转载自:http://www.cnblogs.com/macroxu-1982/archive/2012/10/01/2709960.html 1 实现过程添加libsqlite3组件 选择项目后,在 ...
- mysql 连接多行 合并多行
group_concat() select group_concat(id) from xxxx -------------------------------------------- id1,id ...
- Interlocked.Increment 方法 和Interlocked.Decrement 方法作用
Interlocked.Increment 方法:让++成为原子操作:Interlocked.Decrement 方法让--成为原子操作.什么叫原子操作呢.就是不会被别人打断,因为C#中的一个语句,编 ...
- where, group by, having
where vs having 当一个sql语句中存在where子句,会先执行where,然后执行group by,然后执行having. 一般来说,only use 'having' when yo ...