1687: [Usaco2005 Open]Navigating the City 城市交通
Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 94 Solved: 73
[Submit][Status][Discuss]
Description
由于牛奶市场的需求,奶牛必须前往城市,但是唯一可用的交通工具是出租车.教会奶牛如何在城市里打的.
给出一个城市地图,东西街区E(1≤E≤40),南北街区N(1≤N≤30).制作一个开车指南给出租车司机,告诉他如何从起点(用S表示)到终点(用E表示).每一个条目用空格分成两部分,第一个部分是方向(N,E,S,W之一),第二个是一个整数,表示要沿着这个方向开几个十字路口.如果存在多条路线,你应该给出最短的.数据保证,最短的路径存在且唯一. 地图中“+”表示十字路口,道路用“I”和“一”表示.建筑和其他设施用“.”表示.下面是一张地图:
出租车可以沿着东,北,西,北,东开两个十字路口,以此类推.具体将由样例给出
Input
第1行:两个用空格隔开的整数N和E.
第2到2N行:每行有2E-I个字符,表示地图.
Output
每行有一个表示方向的字母和一个表示要开几个十字路口的数字表示.
Sample Input
Sample Input
Sample Output
E 1
N 1
W 1
N 1
E 2
S 1
E 3
S 1
W 1
N 1
W 1
N 1
E 2
S 1
E 3
S 1
W 1
HINT
Source
题解:一开始没仔细看题的时候以为是灌水法。。。可是后来想到貌似不见得就一条路径,而且题目中貌似说了要最短路径
不知道正解是啥,反正我还是一如既往的逗比——以地图上每个+符号(S、E也算)为节点,建立无向图,然后就成了求最短路径的问题了,然后就是神烦的边spfa边记录路径了,话说这道水题居然写了我好久唉TT
/**************************************************************
Problem:
User: HansBug
Language: Pascal
Result: Accepted
Time: ms
Memory: kb
****************************************************************/ const dir:array[..] of char=('N','E','S','W');
type
point=^node;
node=record
g,w,q:longint;
next:point;
end;
var
i,j,k,l,m,n,x0,y0,x1,y1,x,y,f,r,s,t,v:longint;
map:array[..,..] of longint;
a:array[..] of point;
b,c,g:array[..] of longint;
d:array[..] of longint;
e,h:array[..,..] of longint;
ch:char;
p:point;
procedure add(x,y,z,t:longint);
var p:point;
begin
new(p);p^.g:=y;p^.w:=z;
p^.q:=t;p^.next:=a[x];a[x]:=p;
end;
begin
fillchar(map,sizeof(map),);
readln(n,m);
n:=n*-;m:=m*-;
for i:= to n do
begin
for j:= to m do
begin
read(ch);
case upcase(ch) of
'S':begin
map[i,j]:=-;
x0:=i;y0:=j;
end;
'E':begin
map[i,j]:=-;
x1:=i;y1:=j;
end;
'.':map[i,j]:=;
'-':map[i,j]:=-;
'|':map[i,j]:=-;
'+':map[i,j]:=-;
end;
end;
readln;
end;
s:=;t:=;v:=;
for i:= to n do
for j:= to m do
if map[i,j]=- then
begin
inc(v);
map[i,j]:=v;
if (x0=i) and (y0=j) then s:=v;
if (x1=i) and (y1=j) then t:=v;
end;
for i:= to n do
for j:= to m do
begin
if map[i-,j]<> then
begin
x:=i-;y:=j;
while map[x,y]=- do dec(x);
if map[x,y]> then add(map[i,j],map[x,y],,);
end;
if map[i+,j]<> then
begin
x:=i+;y:=j;
while map[x,y]=- do inc(x);
if map[x,y]> then add(map[i,j],map[x,y],,);
end;
if map[i,j-]<> then
begin
x:=i;y:=j-;
while map[x,y]=- do dec(y);
if map[x,y]> then add(map[i,j],map[x,y],,);
end;
if map[i,j+]<> then
begin
x:=i;y:=j+;
while map[x,y]=- do inc(y);
if map[x,y]> then add(map[i,j],map[x,y],,);
end;
end;
fillchar(g,sizeof(g),);
fillchar(c,sizeof(c),);
fillchar(b,sizeof(b),);
fillchar(e,sizeof(e),);
d[]:=s;f:=;r:=;g[s]:=;c[s]:=;
while f<r do
begin
p:=a[d[f]];
while p<>nil do
begin
if (c[p^.g]=) or ((c[p^.g]>) and (c[p^.g]>(c[d[f]]+p^.w))) then
begin
c[p^.g]:=c[d[f]]+p^.w;
b[p^.g]:=d[f];
e[p^.g,]:=p^.q;e[p^.g,]:=p^.w;
if g[p^.g]= then
begin
g[p^.g]:=;
d[r]:=p^.g;
inc(r);
end;
end;
p:=p^.next;
end;
inc(f);
g[d[f]]:=;
end;
for i:= to v do dec(c[i]);
i:=;fillchar(h,sizeof(h),);
while t<> do
begin
inc(i);
h[i,]:=e[t,];
h[i,]:=e[t,];
t:=b[t];
end;
v:=i-;
for i:= to v div do
begin
j:=h[i,];h[i,]:=h[v+-i,];h[v+-i,]:=j;
j:=h[i,];h[i,]:=h[v+-i,];h[v+-i,]:=j;
end;
inc(v);h[v,]:=;h[v,]:=;
j:=h[,];k:=h[,];
for i:= to v do
begin
if h[i,]=j then
k:=k+h[i,]
else
begin
writeln(dir[j],' ',k);
k:=h[i,];j:=h[i,];
end;
end;
readln;
end.