标签:
const u:array[1..4] of integer=(-1,0,1,0); v:array[1..4] of integer=(0,1,0,-1); oo=100000000; type node=record x,y,cs,l:longint; end; var ft:text; n,m,q,ii,i,i1,j1,j,l,w,x,y,x1,y1,x2,y2,x3,y3,es,ey,wei,tou,kx,ky,ans:longint; r:array[0..5000000] of node; aa,a,fb,fb2:array[0..31,0..31] of longint; ff,z,z2:array[0..31,0..31,1..4] of longint; f:array[0..31,0..31,1..4,1..4] of longint; procedure bfs(x,y:longint); var i,x1,y1:longint; begin wei:=1; tou:=0; r[wei].x:=x; r[wei].y:=y; r[wei].cs:=fb[x,y]; while tou<wei do begin inc(tou); for i:=1 to 4 do begin x1:=r[tou].x+u[i]; y1:=r[tou].y+v[i]; if (a[x1,y1]=1)and(r[tou].cs+1<fb[x1,y1]) then begin inc(wei); r[wei].x:=x1; r[wei].y:=y1; r[wei].cs:=r[tou].cs+1; fb[x1,y1]:=r[wei].cs; end; end; end; end; begin readln(n,m,q); for i:=1 to n do begin for j:=1 to m do read(a[i,j]); readln; end; aa:=a; for i:=1 to n do for j:=1 to m do begin fb2[i,j]:=oo; for l:=1 to 4 do begin z2[i,j,l]:=oo; for w:=1 to 4 do f[i,j,l,w]:=oo; end; end; for i:=1 to n do for j:=1 to m do if a[i,j]=1 then for l:=1 to 4 do begin x:=i+u[l]; y:=j+v[l]; if (x>0)and(x<n+1)and(y>0)and(y<m+1)and(a[x,y]=1) then begin a[x,y]:=0; fb:=fb2; fb[i,j]:=1; bfs(i,j); for w:=1 to 4 do begin x1:=x+u[w]; y1:=y+v[w]; if (x1>0)and(x1<n+1)and(y1>0)and(y1<m+1)and(fb[x1,y1]<oo) then begin f[i,j,l,w]:=fb[x1,y1]; end; end; a[x,y]:=1; end; end; for ii:=1 to q do begin read(kx,ky,x,y,es,ey); if (x=es)and(y=ey) then begin writeln(0); continue; end; fb:=fb2; a[x,y]:=0; fb[kx,ky]:=0; bfs(kx,ky); wei:=0; z:=z2; fillchar(ff,sizeof(ff),0); for j:=1 to 4 do begin x1:=x+u[j]; y1:=y+v[j]; if (x1>0)and(x1<n+1)and(y1>0)and(y1<m+1)and(fb[x1,y1]<oo) then begin inc(wei); r[wei].x:=x; r[wei].y:=y; r[wei].l:=j; z[x,y,j]:=fb[x1,y1]; ff[x,y,j]:=1; end; end; tou:=0; while tou<wei do begin inc(tou); for i:=1 to 4 do begin x2:=r[tou].x; y2:=r[tou].y; x1:=x2+u[r[tou].l]+u[i]; y1:=y2+v[r[tou].l]+v[i]; x3:=x2+u[r[tou].l]; y3:=y2+v[r[tou].l]; if (f[x2,y2,r[tou].l,i]<>oo)and(z[x3,y3,i]>z[x2,y2,r[tou].l]+f[x2,y2,r[tou].l,i]) then begin z[x3,y3,i]:=z[x2,y2,r[tou].l]+f[x2,y2,r[tou].l,i]; if ff[x3,y3,i]=0 then begin ff[x3,y3,i]:=1; inc(wei); r[wei].x:=x3; r[wei].y:=y3; r[wei].l:=i; end; end; end; ff[r[tou].x,r[tou].y,r[tou].l]:=0; end; ans:=oo; for i:=1 to 4 do if z[es,ey,i]<ans then ans:=z[es,ey,i]; if ans=oo then writeln(-1) else writeln(ans); a[x,y]:=1; end; end.
因为对棋子的移动最终对应着对空格的移动,而空格的初始位置(非起始情况)一定是在目标棋子的上下左右的。
这样我们把空格先准备好,然后移动一下棋子,这种操作的代价很容易发现是常数。因此可以使用最短路。方法是把每个棋子一分为四,上下左右,[一个棋 子的左边]就代表了空格的初始位置在这个棋子的左边,即它前一次是从左边移过来的。每个棋子的每一边可以建立于上面棋子的下边,下面棋子的上边等的联系 (用一个有向图来存储),并存储价值。
最后还有一个小问题,就是每次的q的空白位置不是在目标棋子的上下左右。这时候选择目标棋子的一类,并且修改其与周遭棋子联系的边权,然后做最短路,然后记得要改回去。
[noip2013][codevs3290]华容道 bfs+spfa
标签:
原文地址:http://www.cnblogs.com/victorslave/p/4802135.html