The main idea: a n*m in the picture, "." can go, "X" Cannot go, "*" for starting point, ask from beginning to start around all X lap back to start at least how many steps to take.
Beginning to see this problem, their own brain hole how to write, should be able to, and then ran to see the puzzle, and learned a new posture ...
is a sample, red handwriting is the way, need to walk 13 steps.
This is obviously the BFS problem, the question is how to let bfs around this lump of things a circle, very ingenious idea, from any X node to draw a ray perpendicular to the boundary, as shown in.
when we touch this line from right to left BFS, we stop BFS; when we run around a circle from left to right, we touch the line and we go on.
Dist[1][x][y] represents the shortest distance from the beginning to (x, y) from left to right after this line, and Dist[0][x][y] indicates the shortest distance from the beginning to (x, y) without passing through the line. When we pass this line from left to right after the BFS we only update dist[1][x][y], and finally output is dist[1][beginning x][y].
The code is as follows:
ConstDX:Array[1..8] ofInteger= (1,0,-1,0,1,1,-1,-1); DY:Array[1..8] ofInteger= (0,1,0,-1,1,-1,1,-1);varN,m,i,j,fx,fy,tx,ty:longint; s:string; Line,map:Array[0.. -,0.. -] ofBoolean; Dist:Array[0..1,0.. -,0.. -] ofLongint; V:Array[0..1,0.. -,0.. -] ofBoolean; H:Array[0..1000000,1..3] ofLongint;procedureBFS;varI,j,k,front,rear,nx,ny,xx,yy,flag,flag2:longint;begin fori:=1 toN Do forj:=1 toM Do fork:=0 to 1 Dodist[k,i,j]:=23333333; dist[0, fx,fy]:=0; v[0, fx,fy]:=true;front:=0; rear:=1; h[1,1]:=fx;h[1,2]:=fy;h[1,3]:=0; whileFront<>rear Do beginInc (front); NX:=h[front,1];ny:=h[front,2];flag:=h[front,3]; ifFront= + Thenfront:=0; fori:=1 to 8 Do beginXX:=nx+dx[i];yy:=ny+Dy[i]; if(xx<0)or(xx>n)or(yy<0)or(yy>m)or(Map[xx,yy])or((LINE[XX,YY)orLine[nx,ny]) and(Yy<=ny)) Thencontinue; if(Line[xx,yy])or(flag=1) Thenflag2:=1 Elseflag2:=0; ifdist[flag,nx,ny]+1<DIST[FLAG2,XX,YY] Then beginDist[flag2,xx,yy]:=dist[flag,nx,ny]+1; if notV[FLAG2,XX,YY] Then beginV[flag2,xx,yy]:=true; ifRear= + Thenrear:=0; Inc (rear); H[rear,1]:=xx; H[rear,2]:=yy; H[rear,3]:=Flag2; End; End; End; V[flag,nx,ny]:=false; End; Writeln (dist[1, Fx,fy]);End;beginreadln (n,m); fori:=1 toN Do beginReadln (s); forj:=1 toM Do begin ifs[j]='*' Then beginFX:=i;fy:=J; End; ifs[j]='X' Then beginTX:=i;ty:=J; MAP[I,J]:=true; End; End; End; forI:=tx toN DoLine[i,ty]:=true; BFS;End.
View Code
bzoj1656: [Usaco2006 Jan] The Grove of trees (bfs+ new posture)