思路:裸的BFS。每次在四个方向上进行搜索,如果走得通(没有碰到边界或障碍),就将该结点加入队列。该结点的最短路径长度更新为其前驱结点的最短路径长度+1,如果需要重构路径的话,数组中保存该结点的前驱位置,输出的时候倒序输出(利用一个栈)即可。
代码:
// 1252.cpp : 定义控制台应用程序的入口点。
// AC
// BFS求迷宫问题,从左上角走到右下角
#include "stdafx.h"
#include <iostream>
#include <string>
#include <deque>
#define MAX 100
#define INF 1000000
using std::cin;
using std::cout;
using std::endl;
using std::cerr;
using std::string;
using std::deque;
struct Point {
int x;
int y;
Point(int _x, int _y) :x(_x), y(_y) {}
Point() :x(0), y(0) {}
};
//以(x,y)为源点做BFS
void BFS(char a[][MAX], int R, int C, int x, int y, int d[][MAX], bool visit[][MAX], Point prev[][MAX])
{
deque<Point> Q;
Q.push_back(Point(x, y)); //初始化队列
visit[x][y] = true;
d[x][y] = 1;
prev[x][y] = Point(-1,-1);
while (!Q.empty())
{
Point temp = Q.front();
Q.pop_front();
int temp_x = temp.x;
int temp_y = temp.y;
//所有未访问的邻居结点入队列
if (temp_x - 1 >= 0 && temp_x - 1 < R&&temp_y >= 0 && temp_y < C)
{
if (!visit[temp_x - 1][temp_y] && a[temp_x - 1][temp_y] != '#')
{
prev[temp_x - 1][temp_y] = Point(temp_x, temp_y); //记录前驱结点
d[temp_x - 1][temp_y] = d[temp_x][temp_y] + 1; //当前结点的最短路径长度
Q.push_back(Point(temp_x - 1, temp_y));
visit[temp_x - 1][temp_y] = true;
}
}
if (temp_x + 1 >= 0 && temp_x + 1 < R&&temp_y >= 0 && temp_y < C)
{
if (!visit[temp_x + 1][temp_y] && a[temp_x + 1][temp_y] != '#')
{
prev[temp_x + 1][temp_y] = Point(temp_x, temp_y);
d[temp_x + 1][temp_y] = d[temp_x][temp_y] + 1;
Q.push_back(Point(temp_x + 1, temp_y));
visit[temp_x + 1][temp_y] = true;
}
}
if (temp_x >= 0 && temp_x < R&&temp_y - 1 >= 0 && temp_y - 1 < C)
{
if (!visit[temp_x][temp_y - 1] && a[temp_x][temp_y - 1] != '#')
{
prev[temp_x][temp_y - 1] = Point(temp_x, temp_y);
d[temp_x][temp_y - 1] = d[temp_x][temp_y] + 1;
Q.push_back(Point(temp_x, temp_y - 1));
visit[temp_x][temp_y - 1] = true;
}
}
if (temp_x >= 0 && temp_x < R&&temp_y + 1 >= 0 && temp_y + 1 < C)
{
if (!visit[temp_x][temp_y + 1] && a[temp_x][temp_y + 1] != '#')
{
prev[temp_x][temp_y + 1] = Point(temp_x, temp_y);
d[temp_x][temp_y + 1] = d[temp_x][temp_y] + 1;
Q.push_back(Point(temp_x, temp_y + 1));
visit[temp_x][temp_y + 1] = true;
}
}
}
}
int main()
{
int R, C;
cin >> R >> C;
char a[MAX][MAX];
string temp;
for (int i = 0; i < R; i++)
{
cin >> temp;
for (int j = 0; j < C; j++)
a[i][j] = temp[j];
}
int d[MAX][MAX];
for (int i = 0; i < R; i++)
for (int j = 0; j < C; j++)
{
d[i][j] = INF;
}
bool visit[MAX][MAX];
for (int i = 0; i < R; i++)
for (int j = 0; j < C; j++)
{
visit[i][j] = false;
}
Point prev[MAX][MAX];
BFS(a, R, C, 0, 0, d, visit, prev);
//最短路径长度
cout << d[R - 1][C - 1] << endl;
//打印路径(倒序)
cout << "routing:" << endl;
int i = R - 1, j = C - 1;
cout << i << " " << j << endl;
while (prev[i][j].x != -1)
{
cout << prev[i][j].x << " " << prev[i][j].y << endl;
int temp_i = prev[i][j].x;
int temp_j = prev[i][j].y;
i = temp_i;
j = temp_j;
}
system("pause");
return 0;
}
运行结果: