1. 程式人生 > >迷宮問題BFS和DFS(模板)

迷宮問題BFS和DFS(模板)

迷宮問題BFS和DFS(模板)

DFS的基本結構:

void dfs(int 引數1,int 引數2)  
{  
	    if(不滿足要求) return;    //剪枝條件
	    if(達到目標值)  
	    {  
	        儲存當前答案;  
	        return;  
	    }  
	    dfs(下一步);  
}

模板程式碼如下:

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
/*
迷宮問題的廣度優先搜尋和深度優先搜尋
.表示路,#表示牆
起點[0,0],終點[n-1][m-1]
*/ 
struct node
{
	int x;  //縱軸座標 
	int y;  //橫軸座標 
};
int dx[4]={0,1,0,-1};  //縱座標的變化 
int dy[4]={1,0,-1,0};  //橫座標的變化 
int n,m;  //行數,列數 
char maze[25][25];  //儲存迷宮的陣列 
bool vis[25][25];   //標記陣列 
int dir[25][25];   //距離陣列 
void bfs(node start)  //廣度優先搜尋 
{
	node normal,temp;
	int xx,yy; 
	queue<node>q;   //定義一個儲存座標的佇列 
	while(!q.empty())   q.pop(); //清空佇列
	q.push(start);   //存入開始座標 
	dir[start.x][start.y]=0;   //標記此點的步數為0 
	while(!q.empty())  //迴圈條件是佇列不為空 
	{
		normal=q.front();  //取出佇列中的座標 
		q.pop();  //刪除座標 
		vis[normal.x][normal.y]=true;   //標記此座標已經走過 
		for(int i=0;i<4;i++)   //迴圈遍歷四個方向 
		{
			xx=normal.x+dx[i];  yy=normal.y+dy[i];
			if(xx>=0&&xx<n&&yy>=0&&yy<m&&maze[xx][yy]=='.'&&!vis[xx][yy])
			{   //座標不超出座標系範圍,並且是路不是牆,而且從來沒有走過 
				temp.x=xx;   temp.y=yy;
				q.push(temp);  //加入佇列 
				dir[xx][yy]=dir[normal.x][normal.y]+1;  //走到此點是前一點的步數加一 
			}
		}
	}
}
void dfs(int xx,int yy)  //深度優先搜尋 
{
	if(xx>=n || yy>=m || xx<0 || yy<0 || vis[xx][yy] || maze[xx][yy]=='#') return;
	//判斷是否滿足剪枝條件
    if(xx==n-1 && yy==m-1) 
	{
		cout<<"have way!"<<endl;
		return;
	}
	vis[xx][yy]=true;   //標誌此地走過
	for(int k=0;k<4;k++)
		dfs(xx+dx[k],yy+dy[k]);   //往四個方向走
}
int main()
{
	node start;
	while(cin>>n>>m)  //n代表列數,m代表行數 
	{
		if(n==0&&m==0)  break;  
		memset(dir,0,sizeof(dir));  //初始化步數陣列 
		memset(vis,false,sizeof(vis));  //初始化軌跡陣列 
		for(int i=0;i<n;i++)
		   for(int j=0;j<m;j++)
		   {
		   	  cin>>maze[i][j];  //輸入迷宮 
		   }
		start.x=0;  start.y=0;   //設定起點 
		memset(vis,false,sizeof(vis));  //初始化軌跡陣列 
		bfs(start);    //開始廣搜 
		if(dir[n-1][m-1]==0)  cout<<"no way!"<<endl;  //無法到達 
		else cout<<"need "<<dir[n-1][m-1]<<" steps"<<endl;   //可以到達,輸出步數 
		memset(vis,false,sizeof(vis));   //初始化軌跡陣列 
		dfs(0,0); 
	}
	return 0;
}
/*
3 3
..*
*.*
*..
5 5
.....
###.#
..#..
###..
...#.
*/