迷宫的最短路径问题,分别用DFS和BFS做

迷宫的最短路径一般来说用BFS做,但是也可以用DFS做,如果最优路径只有一条的话,穷尽所有的路径然后找出路径最短的就好了。

不废话,先上BFS代码,这个代码中,用到了每一个位置的前驱节点,需要记住。然后逆着路径打印出来。

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
typedef pair<int, int> pii;
void bfs(int a[10][10], int m, int n,int i, int j, pii pre[10][10])
{
	queue<pii> 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<iostream>
#include<vector>
using namespace std;
typedef pair<int, int> pii;
 
void dfs(int &min_t, int a[10][10], int m, int n, int i, int j, vector<pii> tmp, vector<vector<int>> visited, vector<vector<pii>> &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<m; i++)
        {
            for (int j = 0; j<n; j++)
            {
                cin >> a[i][j];
            }
        }
        vector<pii> res;
        vector<vector<int>> visited(m, vector<int>(n, false));
        vector<vector<pii>> 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<iostream>
#include<vector>
using namespace std;
 
int N, M; //分别代表行和列
vector<vector<int>> maze;//迷宫矩阵
vector<vector<int>> path_temp;//存储当前路径,第一维表示位置
vector<vector<int>> 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<vector<int>>(N, vector<int>(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;
}
    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/yecuandu1534/article/details/80304410
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞