迷宫的最短路径一般来说用BFS做,但是也可以用DFS做,如果最优路径只有一条的话,穷尽所有的路径然后找出路径最短的就好了。
不废话,先上BFS代码,这个代码中,用到了每一个位置的前驱节点,需要记住。然后逆着路径打印出来。
#include
#include
#include
using namespace std;
typedef pair pii;
void bfs(int a[10][10], int m, int n,int i, int j, pii pre[10][10])
{
queue q;
if (a[i][j] == 0)
{
q.push({ i, j });
}
while (!q.empty())
{
pii tmp = q.front();
q.pop();
if (tmp.first + 1 < m && a[tmp.first + 1][tmp.second] == 0)
{
pre[tmp.first + 1][tmp.second] = tmp;
q.push({ tmp.first + 1, tmp.second });
if (tmp.first + 1 == m - 1 && tmp.second == n - 1)
break;
}
if (tmp.second + 1 < n && a[tmp.first][tmp.second + 1] == 0)
{
pre[tmp.first][tmp.second + 1] = tmp;
q.push({ tmp.first, tmp.second + 1 });
if (tmp.first == m - 1 && tmp.second + 1 == n - 1)
break;
}
if (tmp.first - 1 >= 0 && a[tmp.first - 1][tmp.second] == 0)
{
pre[tmp.first - 1][tmp.second] = tmp;
q.push({ tmp.first - 1, tmp.second });
if (tmp.first - 1 == m - 1 && tmp.second == n - 1)
break;
}
if (tmp.second - 1 >= 0 && a[tmp.first][tmp.second - 1] == 0)
{
pre[tmp.first][tmp.second - 1] = tmp;
q.push({ tmp.first, tmp.second - 1 });
if (tmp.first == m - 1 && tmp.second - 1 == n - 1)
break;
}
a[tmp.first][tmp.second] = 1;
}
}
void print(pii res[100], pii pre[10][10],int m,int n,int i,int j)
{
int count = 0;
// 逆序搜索,放入路径数组中
res[count].first = m - 1;
res[count].second = n - 1;
while(1) {
if (res[count].first == i && res[count].second == j)
break;
res[count + 1] = pre[res[count].first][res[count].second];
count++;
}
// 顺序输出结果
while (count >= 0) {
printf("(%d,%d)\n", res[count].first, res[count].second);
count--;
}
}
int main()
{
int m, n;
while (cin >> m >> n)
{
int a[10][10];
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
cin >> a[i][j];
}
pii res[100];
pii pre[10][10] ;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
pre[i][j] = make_pair(-1, -1);
}
bfs(a, m, n, 0,0, pre);
print(res, pre, m, n, 0,0);
/*
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
cout << pre[i][j].first << ' ' << pre[i][j].second << endl;
}
*/
}
return 0;
}
下面写两种DFS的代码:
方法1:朴素的DFS
#include
#include
using namespace std;
typedef pair pii;
void dfs(int &min_t, int a[10][10], int m, int n, int i, int j, vector tmp, vector> visited, vector> &res)
{
if (i < 0 || i >= m || j < 0 || j >= n || a[i][j] == 1 || visited[i][j]) return;
if (!visited[i][j]) tmp.push_back(make_pair(i, j));
visited[i][j] = true;
if (i == m - 1 && j == n - 1)
{
res.push_back(tmp);
if (tmp.size() < min_t)
min_t = tmp.size();
return;
}
dfs(min_t,a, m, n, i + 1, j, tmp, visited, res);
dfs(min_t,a, m, n, i - 1, j, tmp, visited, res);
dfs(min_t,a, m, n, i, j + 1, tmp, visited, res);
dfs(min_t,a, m, n, i, j - 1, tmp, visited, res);
}
int main()
{
int m, n;
int a[10][10];
while (cin >> m >> n)
{
for (int i = 0; i> a[i][j];
}
}
vector res;
vector> visited(m, vector(n, false));
vector> ret;
int min_t = 101;
dfs(min_t ,a, m, n, 0, 0, res, visited, ret);
for (int i = 0; i < ret.size(); i++)
{
if (min_t == ret[i].size())
{
for (int k = 0; k < min_t; k++)
{
cout << '(' << ret[i][k].first << ',' << ret[i][k].second << ')' << endl;
}
}
}
}
system("pause");
return 0;
}
方法2:
#include
#include
using namespace std;
int N, M; //分别代表行和列
vector> maze;//迷宫矩阵
vector> path_temp;//存储当前路径,第一维表示位置
vector> path_best;//存储最佳路径
void MazeTrack(int i, int j)
{
maze[i][j] = 1;//表示当前节点已走,不可再走
path_temp.push_back({ i, j });//将当前节点加入到路径中
if (i == N - 1 && j == M - 1) //判断是否到达终点
if (path_best.empty() || path_temp.size() < path_best.size())
path_best = path_temp;
if (i - 1 >= 0 && maze[i - 1][j] == 0)//探索向上走是否可行
MazeTrack(i - 1, j);
if (i + 1 < N && maze[i + 1][j] == 0)//探索向下走是否可行
MazeTrack(i + 1, j);
if (j - 1 >= 0 && maze[i][j - 1] == 0)//探索向左走是否可行
MazeTrack(i, j - 1);
if (j + 1 < M && maze[i][j + 1] == 0)//探索向右走是否可行
MazeTrack(i, j + 1);
maze[i][j] = 0; //恢复现场,设为未走
path_temp.pop_back();
}
int main()
{
while (cin >> N >> M)
{
maze = vector>(N, vector(M, 0));
path_temp.clear();
path_best.clear();
for (auto &i : maze)
for (auto &j : i)
cin >> j;
MazeTrack(0, 0);//回溯寻找迷宫最短通路
for (auto i : path_best)
cout << '(' << i[0] << ',' << i[1] << ')' << endl;//输出通路
}
return 0;
}