1. 程式人生 > >解救小哈——DFS演算法舉例

解救小哈——DFS演算法舉例

有一天,小哈一個人去玩迷宮。但是方向感不好的小哈很快就迷路了。小哼得知後便去解救無助的小哈。此時的小哼已經弄清楚了迷宮的地圖,現在小哼要以最快的速度去解救小哈。那麼,問題來了...

輸入

5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3

輸出

7

 

輸入

3 3
1 1 1 
0 1 0 
0 1 0 
2 1 3 3

輸出

No Way!

思路:走過每一條可能找到小哈的路徑選出最短的一條,即遍歷所有路徑,記錄minstep。

用二維陣列儲存迷宮,再用二維陣列建立一個移動鍵。

dfs()需要控制三個引數,當前座標x,y與當前所走步數。

#include <iostream>
using namespace std;	
int n,m;
int hax,hay;
int minstep=9999;
const int MAX=105;
int str[MAX][MAX];               //初始迷宮
int vis[MAX][MAX];               //記錄迷宮 
void dfs(int x,int y,int step)
{
	int next[4][2]={{0,1},//向上走
	                {0,-1},//向下走
		     		{-1,0},//向左走
		    		{1,0}//向右走
		     	   };
	if(x==hax&&y==hay)            //判斷是否到達小哈的座標 
	{
		step<minstep?minstep=step:minstep=minstep;
		return ;
	}
	int tx,ty;                     //移動後坐標 
	for(int i=0;i<4;i++)
	{
		tx=x+next[i][0];            //+移動座標 
		ty=y+next[i][1];            //+移動座標 
		if(tx<1||tx>n||ty<1||ty>m)  //判斷越界 
		{
			continue;                //越界 
		}
		if(str[tx][ty]==0&&vis[tx][ty]==0)     //判斷是否為障礙,是否已經走過 
		{
			vis[tx][ty]=1;            //標記走過 
			dfs(tx,ty,step+1);        //執行下一步 
			vis[tx][ty]=0;            //最後取消標記 
		}
	}
	return ;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)            //注意!這裡從1開始輸入 和  上面 tx<1相對應 
	{
		for(int j=1;j<=m;j++)
		{
			cin>>str[i][j];
		}
	}
	int startx,starty;               //初始座標 
	cin>>startx>>starty>>hax>>hay;
	vis[startx][starty]=1;           //初始座標標記為走過 
	dfs(startx,starty,0);            //從步數為0開始執行 
	cout<<minstep<<endl;             //若minstep=9999,說明沒有可執行方案 
	return 0;
}