链接:
http://poj.org/problem?id=3984
题意:
给定迷宫的障碍物,求解走迷宫的最短路径
思路:
BFS,因为BFS对应着层次遍历,同一层次的点,会在一起遍历,不同层次内的点,其层次也必定是相隔1
如果没记录BFS的过程中,每一个点的前驱,那么到了最后,还需要通过递归(或者其他形式)将路线再还原,这样会增加循环复杂度,故而我们可以记录每个点的前驱,在抵达终点以后,再通过其前驱,不断找到其之前的对应结点,直到起点,并将这些点压栈后输出(压栈是因为,本来,通过不断找其pre节点,找到的,是从终点找到起点这一方向的路线,通过栈,将其变成从起点到终点的方向)
代码:
#include <iostream>
#include <queue>
#include <stack>
#include <cstring>
#define Clear(x, y) memset(x, y, sizeof(x))
int d[4][2] = { {-1, 0}, {1, 0}, {0, 1}, {0, -1} };
using namespace std;
const int N = 5; // 迷宫维度
const int M = 25; //路线数组上限
struct Node
{
int x, y;
Node(int _x = 0, int _y = 0):x(_x), y(_y)
{
}
int isin()
{
if (x >= 0 && x < N && y >= 0 && y < N) return 1;
return 0;
}
};
Node pre[N][N];
int vis[N][N];
int maze[N][N];
void display()
{
Node now = Node(N - 1, N - 1);
stack<Node>way;
while (true)
{
way.push(now);
if (now.x == 0 && now.y == 0)
{
break;
}
now = pre[now.x][now.y];
}
while (!way.empty())
{
now = way.top();
cout << "(" << now.x << ", " << now.y << ")" << endl;
way.pop();
}
}
void bfs()
{
queue<Node> q;
q.push(Node(0, 0));
while (!q.empty())
{
Node now = q.front();
vis[now.x][now.y] = 1;
if (now.x == N - 1 && now.y == N - 1)
{
display();
break;
}
q.pop();
for (int i = 0; i < 4; i++)
{
Node next = Node(now.x + d[i][0], now.y + d[i][1]);
if (next.isin() && !vis[next.x][next.y] && !maze[next.x][next.y])
{
vis[next.x][next.y] = 1;
q.push(next);
pre[next.x][next.y] = now;
}
}
}
}
int main()
{
Clear(pre, 0);
Clear(vis, 0);
Clear(maze, 0);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
cin >> maze[i][j];
bfs();
return 0;
}