起点到终点,’X‘处不用时,’ . '用时为1,求到达终点的最小时间。
因为当前状态的下一个状态不能确定,所以如果用普通广搜的话,必须将整个图遍历一遍,但是此题的n*m可能为1000*1000,必定超时。所以考虑用优先队列。即,每次探查到的点入队列时,不是直接放到队尾,放在队列中合适的位置(此元素前面的元素比它“小”,后面的元素比它“大”),这样才能保证,首先探查到终点的路径为所需“最短”路径。
则循环结束的条件为: cur.x==ex&&cur.y==ey。
代码如下(参考别人所得):
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
char map[1010][1010];
int vis[1010][1010];
typedef struct p
{
int x,y;
int step;
p(int a=0): step(a){}; //构造函数,另每个结构中的step初始值为0
const bool operator < (const struct p&p1)const
{
return step>p1.step; //队列中需要使用的比较排序函数,
} //此处,p1.step<step的话,p1将在队列前面。
}P;
int n,m;
int d[4][2]={-1,0,1,0,0,1,0,-1};
int bfs(int sx,int sy,int ex,int ey)
{
priority_queue <P> q;
P next,cur;
cur.x=sx; cur.y=sy;
cur.step=0;
vis[cur.x][cur.y]=1;
while(!q.empty()) q.pop();
q.push(cur);
while (!q.empty())
{
cur=q.top(); q.pop();
for(int i=0;i<4;i++)
{
next.x=cur.x+d[i][0]; next.y=cur.y+d[i][1];next.step=cur.step;
if (next.x>=1&&next.x<=n&&next.y>0&&next.y<=m)
{
if(vis[next.x][next.y]==0)
{
if(map[next.x][next.y]=='.')
next.step=cur.step+1;
if(next.x==ex&&next.y==ey) //若探查到的点恰为终点,结束。
return next.step; q.push(next);
vis[next.x][next.y]=1;
}
}
}
}
return -1;
}
int main()
{
int x0,y0,x1,y1;
char str[1010];
while (scanf("%d%d",&n,&m)!=EOF&&n!=0&&m!=0)
{
memset(vis,0,sizeof(vis));
for (int i=1;i<=n;i++)
{
scanf("%s",map[i]+1); //让数据从map[i][1]开始。
}
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
printf("%d\n",bfs(x0,y0,x1,y1));
}
return 0;
}