廣度優先搜尋 Part1

2021-09-29 06:47:48 字數 1899 閱讀 1806

農夫知道一頭牛的位置,想要抓住它。農夫和牛都位於數軸上,農夫起始位於點n(0<=n<=100000),牛位於點k(0<=k<=100000)。農夫有兩種移動方式:

1、從x移動到x-1或x+1,每次移動花費一分鐘

2、從x移動到2*x,每次移動花費一分鐘

假設牛沒有意識到農夫的行動,站在原地不動。農夫最少要花多少時間才能抓住牛?

假設農夫起始位於3,牛位於5,如何搜尋一條到5的路徑?

策略一:深度優先搜尋:

從起點出發,隨機挑選乙個方向,能往前走就往前走(擴充套件),走不動了則回溯。

運氣好的話: 3->4->5

運氣最壞的話: 3->2->1->0->4->5

如果想要求最優解,需要遍歷所有走法,但可以使用一定方法進行剪枝。

運算過程中需要儲存路徑上的節點,數量較少,用棧儲存。

策略二:廣度優先搜尋

給節點分層。起點就是第0層,從起點最少需要n步就能到達的點就屬於第n層。

依層次順序,從小到大的擴充套件節點。把層次低的點全部擴充套件出來後,才會擴充套件層次高得點。

搜尋過程:

12 4 6

1 5注意:擴充套件時,不能擴充套件已經走過的節點。可確保找到最優解,但是因擴充套件出 來的節點較多,且多數節點都需要 儲存,因此需要的儲存空間較大。 用佇列存節點。

廣度優先搜尋演算法如下:(用queue )

把初始節點s0放入open表中;

如果open表為空,則問題無解,失敗 退出;

把open表的第乙個節點取出放入 closed表,並記該節點為 n ;

考察節點 n是否為目標節點。若是, 則得到問題的解,成功退出;

若節點 n不可擴充套件,則轉第(2)步;

擴充套件節點 n,將其不在closed表和 open表中的子節點 (判重)放入open表的尾部 ,並為每乙個子節點設定指向父節點的指標 ( 或記錄節點的層次),然後轉第(2)步

**實現如下:

#include

#include

#include

using

namespace std;

int n, k;

const

int maxn =

100000

;int visited[maxn +10]

;//判重標記,為true表示該點已經擴充套件過了

struct step};

queue q;

//佇列,即open表

intmain()

else

if(s.x +

1<= maxn &&

!visited[s.x +1]

)if(s.x *

2<= maxn &&

!visited[s.x *2]

) q.

pop();

}}return0;

}

廣搜一般用於狀態表示比較簡單、求最優策略的問題

缺點:盲目性較大,尤其是當目標節點距初始節點較遠時,將產 生許多無用的節點,因此其搜尋效率較低。

需要儲存所有擴充套件出 的狀態,占用的空間大

深搜幾乎可以用於任何問題

dbfs演算法是對bfs演算法的一種擴充套件。

dbfs演算法相對於bfs演算法來說,由於採用了雙向擴充套件的方式,搜尋樹的寬度得到了明顯的減少,所以在演算法的時間複雜度和空間 複雜度上都有較大的優勢。

int

expand

(i)//其中i為佇列的編號,0或1

廣度優先搜尋1

乙個人站在n點,只能向左走一步,或者向右走一步,或者直接走n的2倍步,要求走最少的步數抓住站在k點的牛。include define max 200005 定義最大值 using namespace std int cnt v 3000000 初始化 void bfs int n,int k 廣搜 ...

搜尋(廣度優先搜尋) BFS 1

廣度優先搜尋 bfs 狀態查詢樹 剪枝 題目1456 勝利大逃亡 題目描述 ignatius被魔王抓走了,有一天魔王出差去了,這可是ignatius逃亡的好機會.魔王住在乙個城堡裡,城堡是乙個a b c的立方體,可以被表示成a個b c的矩陣,剛開始ignatius被關在 0,0,0 的位置,離開城堡...

搜尋 廣度優先搜尋

廣度優先搜尋一層一層地進行遍歷,每層遍歷都是以上一層遍歷的結果作為起點,遍歷乙個距離能訪問到的所有節點。需要注意的是,遍歷過的節點不能再次被遍歷。class solution,int shortestpathbinarymatrix vectorint grid length return 1 cl...