DFS--求解迷宫问题

问题:从(0,0)出发到(n-1,m-1)的路径

输入:

6 8
0 0 1 0 0 0 1 1
1 0 0 0 1 0 0 0 
0 0 0 1 1 0 1 1 
1 1 0 1 0 0 0 0
0 0 0 0 0 1 0 1
1 0 1 0 0 0 0 0 
输出:

(0,0)
(0,1)
(1,1)
(1,2)
(1,3)
(0,3)
(0,4)
(0,5)
(1,5)
(2,5)
(3,5)
(3,6)
(4,6)
(5,6)
(5,7)

解题思路:就是dfs搜索,起点是(0,0),终点是(n-1,m-1),如果到达终点就直接返回,否则递归dfs搜索其上下左右四个方向的

点,这四个方向可用int move[4][2]={{0,1},{1,0},{0,-1},{-1,0}};表示,四个方向要满足一下条件才能被访问,1 就是未被访问过visited[i][j]==0且是通道map[i][j]==0,才能访问,注意因为求的是路径,所以根据递归的特点先返回的是终点,所以可以用栈来存放,然后逐个pop就是正确的路径顺序了。但是dfs求的不是最短的路径,而bfs求的是最短路径。需要用到队列。

总结:

①从起点开始dfs满足条件将起点入栈

②开始遍历该点的四周(就像图中的访问到该点时,就要遍历与其相连且未被访问的点,满足条件再dfs

只不过visited是一维数组作为标记是否访问过)

③:四周满足条件的标记好已访问再dfs,然后返回 1;

④:就是不断的pop。直到栈为空

#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
typedef pair<int,int> p;
const int N=500;
int visited[N][N],map[N][N];
int dfs(int x,int y);
int move[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int n,m;
stack<p>s;
int main(){
	cin>>n>>m;
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			cin>>map[i][j];
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			visited[i][j] = 0;  
    if(dfs(0,0)){
    	 s.push(make_pair(0,0));
    }
    while(!s.empty()){
    	p t = s.top();
    	cout<<"("<<t.first<<","<<t.second<<")"<<endl;
    	s.pop();
    }
    return 0;
}
int dfs(int x,int y){
	visited[x][y] = 1;
	if(x==n-1&&y==m-1)return 1;
	for(int i=0;i<4;i++){
		int x1 = x+move[i][0];
		int y1 = y+move[i][1];
		if(x1<n&&y1<m&&x1>=0&&y1>=0&&visited[x1][y1]==0&&map[x1][y1]==0){
			visited[x1][y1] = 1;
			if(dfs(x1,y1)){
				s.push(make_pair(x1,y1));
				return 1;
			}			
		}
	}
return 0;
}






猜你喜欢

转载自blog.csdn.net/qq_38558834/article/details/79747213