基礎演算法 深度優先搜尋DFS與廣度優先搜尋BFS

2021-09-25 17:52:56 字數 1869 閱讀 9697

深搜(depth first search)和廣搜(breadth first search)是兩種基本搜尋演算法,均採用窮舉策略

下面以老鼠走迷宮(maze.cpp)為例給出它們的模板

【問題描述】

乙隻老鼠從迷宮的左上角走到右下角(如下圖),中間不能穿越障礙(陰影部分)

任務:給出迷宮的形狀,請你求出老鼠經過的最少格仔數量。

【輸入格式】

第一行,為兩個整數n和m(1≤n,m≤20),表示迷宮總共有幾行幾列;

從第二行開始到第n+1行,每行m列為迷宮形狀,「0」表示無障礙,「1」表示有障礙,

相鄰連個數中間用乙個空格隔開。

【輸出格式】

輸出乙個整數,表示經過的最短路徑長度(每個格仔長度為1);

如果沒有一條可行的路,則輸出「-1」 。

【輸入樣例】maze.in

6 90 0 0 1 1 0 0 0 1

0 1 0 0 0 0 1 0 1

0 1 0 1 0 1 1 0 1

0 1 0 1 0 0 0 0 0

0 1 1 0 1 1 0 1 0

0 0 0 0 0 0 0 1 0

【輸出樣例】maze.out

14深搜的思想是從乙個起點開始,單向向前進,遇到不合法的情況就回溯。

void dfs( 狀態i )

按這個模型,得到maze.cpp的深搜法**:

//dfs

#includeusing namespace std;

int n,m,x,y;

bool map[21][21],way[21][21];//map記錄障礙,way記錄是否走過

const int fx[4]=;//老鼠向四個方向移動,點的變化量(上,右,下,左)

const int fy[4]=;

int len=0x7f7f7f;//len是進過距離的最小值

void dfs(int step,int a,int b) //準備進行第step步,當前位置a,b }}

int main()

當然,既然我們只求最短路徑長度,可以對深搜過程進行優化:

//判斷新位置是否合法,不合法就不能走,跳到下乙個for迴圈 

if(x>0&&x<=n&&y>0&&y<=m&&!map[x][y]&&!way[x][y])

}

佇列:12

3(1得到)

4(1得到)

5(2得到)

6(2得到)

7(3得到)

……狀態1

狀態2狀態3

狀態4狀態5

狀態6狀態7

……按這個模型,得到maze.cpp的廣搜法**:

#includeusing namespace std;

int n,m,head,tail;//head,tail分別為佇列的頭指標與尾指標--也就是下標

bool map[105][105],way[105][105];

const int fx[4]=;

const int fy[4]=;

int x,y,len;

struct st

;st loc[10005];//定義為佇列陣列--佇列只是模型

void bfs()

}} }

puts("-1");//程式自然結束,沒有到過終點

return;

}int main()

深度優先搜尋演算法(DFS)

1.深度優先搜尋屬於圖的遍歷演算法的一種,英文縮寫為dfs即depth first search.其過程簡要來說是對每乙個可能的分支路徑深入到不能再深入為止,而且每個節點只能訪問一次。2.搜尋策略 深度優先遍歷圖的方法是,從圖中某頂點v出發 1 訪問頂點v 2 依次從v的未被訪問的鄰接點出發,對圖進...

深度優先搜尋 DFS 演算法摘記

圖的表示 對於圖g v,e 可以用兩種標準表示方法表示。一種表示法是將圖作為鄰接鍊錶的組合,另一種是將圖作為鄰接矩陣來看待。鄰接鍊錶 鄰接鍊錶表示由乙個包含 v 條鍊錶的陣列adj所構成,每個結點有一條鍊錶。對於每個結點u,鄰接鍊錶adj u 包含所有與結點u之間有邊相連的結點v。鄰接鍊錶在表示稀疏...

DFS深度優先搜尋演算法

例題一 題目大意 約翰的農場被暴風雨給淹沒了,損失很大,他的保險公司將支付給他,但是支付金額取決於被淹沒的最大面積。這個農場是乙個邊長分別為n m的矩形,包含nm個空間,每個空間要麼是幹的,要麼是被淹沒的,一共有k個空間被淹沒。求最大的淹沒面積。ac include include include ...