您的位置:首页 > 其它

迷宫问题DFS

2014-10-07 13:56 162 查看
        二维整数矩阵a

表示一个迷宫,矩阵左上角表示迷宫入口,右下角表示出口。矩阵的元素为0表示可以通过,为1表示不能够通过。如

maze[5][5]=

{0, 1, 1, 1, 1,

 0, 0, 0, 0, 0,

 0, 1, 0, 1, 0,

 0, 1, 0, 1, 0,

 0, 0, 0, 0, 0};

则迷宫的一条通往出口的路径为(0, 0)->(1, 0)->(2, 0)->(3, 0)->(4, 0)->(4, 1)->(4, 2)->(4, 3)->(4, 4)。

设计一个算法,求通往迷宫出口的所有路径。

       可以考虑使用DFS算法,将已经访问过的矩阵元素做一个标记,以防止路径产生回路,从而产生死循环。但是,简单的对元素进行访问标记会遗漏一些路径。

这是因为,通往迷宫出口的不同路径有可能有交点。当所有路径的交点多于两个时,由于先获取的路径会将交点元素标记为已经访问。当存在其他通过该节点的路径

时,由于该交点已经被标记为已访问,所以其他的通过该交点的路径将被忽略。

      解决这个问题只需要对算法稍加改动即可。思路为:当某一个节点DFS完成后,擦除该节点的访问痕迹。

代码如下:

#include<iostream>
#include<deque>
using namespace std;

class Point
{

public:
int i;
int j;
Point(int x, int y)
{
i=x;
j=y;
}
};// 节点坐标结构体

deque<Point> q;// 用一个队列记录路径
int N=5;// 迷宫的大小
int maze[5][5]=
{0, 1, 1, 1, 1,
0, 0, 0, 0, 0,
0, 1, 0, 1, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0};// 迷宫矩阵
int path[5][5]=
{0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0};// 访问标记矩阵

void dfs(int i, int j);

void main()
{
path[0][0]=1;
q.push_back(Point(0, 0));
dfs(0, 0);
q.pop_back();
//system("pause");
}

void dfs(int i, int j)
{
if(N-1==i && N-1==j)
{
path[i][j]=0;
cout<<"Path:"<<endl;
for(deque<Point>::iterator it=q.begin(); it!=q.end(); it++)
{
cout<<(*it).i<<", "<<(*it).j<<endl;
}
return;
}
if(i>0 && 1!=maze[i-1][j] && 1!=path[i-1][j])
{
path[i-1][j]=1;// 标记节点已经被访问过,避免路径产生回路,从而产生死循环
q.push_back(Point(i-1, j));
dfs(i-1, j);
q.pop_back();
//path[i-1][j]=0;
}
if(i<N-1 && 1!=maze[i+1][j] && 1!=path[i+1][j])
{
path[i+1][j]=1;
q.push_back(Point(i+1, j));
dfs(i+1, j);
q.pop_back();
//path[i+1][j]=0;
}
if(j>0 && 1!=maze[i][j-1] && 1!=path[i][j-1])
{
path[i][j-1]=1;
q.push_back(Point(i, j-1));
dfs(i, j-1);
q.pop_back();
//path[i][j-1]=0;
}
if(j<N-1 && 1!=maze[i][j+1] && 1!=path[i][j+1])
{
path[i][j+1]=1;
q.push_back(Point(i, j+1));
dfs(i, j+1);
q.pop_back();
//path[i][j+1]=0;
}
path[i][j]=0;// 擦除访问痕迹
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息