描述:虽然水题,但错了几次,才对。。要明白优先队列的原理。。就很容易掌握了,得心应手。。题意:起点到终点,’X‘处不用时,’ . '用时为1,求到达终点的最小时间。 优点:因为当前状态的下一个状态不能确定,所以如果用普通广搜的话,必须将整个图遍历一遍,但是此题的n*m可能为1000*1000,必定超时。所以考虑用优先队列。即,每次探查到的点入队列时,不是直接放到队尾,放在队列中合适的位置(此元素前面的元素比它“小”,后面的元素比它“大”),这样才能保证,首先探查到终点的路径为所需“最短”路径。 则循环结束的条件为: cur.x==ex&&cur.y==ey。
#include<stdio.h>
#include<string.h>
#include<queue>
char
map[1010][1010];
int
visit[1010][1010];
int
dir[4][2]={-1,0, 1,0, 0,1, 0,-1};
using
namespace
std;
int
n,m;
struct
point
{
int
x,y;
int
step;
friend
bool
operator<(point a,point b)
{
return
a.step>b.step;
}
};
int
judge(
int
x,
int
y)
{
if
(x<=0||x>n||y<=0||y>m||visit[x][y])
//这里注意由于问法不同,从一开始了。。
return
0;
return
1;
}
int
bfs(
int
x0,
int
y0,
int
x1,
int
y1)
{
int
i,j;
priority_queue<point>q;
point in,out;
in.x=x0;
in.y=y0;
in.step=0;
visit[x0][y0]=1;
q.push(in);
while
(!q.empty())
{
out=q.top();
q.pop();
if
(out.x==x1&&out.y==y1)
{
printf
(
"%dn"
,out.step);
return
1;
}
for
(i=0;i<4;i++)
{
in.x=out.x+dir[i][0];
in.y=out.y+dir[i][1];
in.step=out.step;
if
(judge(in.x,in.y)==0)
continue
;
if
(map[in.x][in.y]==
'.'
)
in.step++;
visit[in.x][in.y]=1;
q.push(in);
}
}
return
0;
}
int
main()
{
int
i,j;
int
a,b,c,d;
while
(
scanf
(
"%d%d"
,&n,&m),n||m)
{
for
(i=1;i<=n;i++)
scanf
(
"%s"
,map[i]+1);
//让数据从map[i][1]开始。
scanf
(
"%d%d"
,&a,&b);
scanf
(
"%d%d"
,&c,&d);
memset
(visit,0,
sizeof
(visit));
if
(bfs(a,b,c,d)==0)
printf
(
"-1n"
);
}
return
0;
}