簡單搜尋 DFS BFS

2021-08-20 12:59:40 字數 1117 閱讀 7280

簡單搜尋——dfs&bfs

dfs:俗稱爆搜,為深度優先搜尋 bfs:俗稱廣搜,為寬度優先搜尋

假設當前有一棵解答樹(當然一般非標準樹形):

dfs借助棧一路下通,直通到最後一層(即已算出乙個可行解),再退一層,看看在這一層還有沒有其他分支,有就繼續扎下去……重複這個過程——

so,這就是所謂的「dfs可以解任何題目」:只要照題目意思不斷嘗試,重新整理最優可行解即可

當然,一般來說,不加優化的dfs通常會效率極低(指數級),因為往往會重複遍歷重複的狀態

這時,往往便加一些可行性剪枝或進行記憶化來減少遍歷次數 而且對於有些上寬下窄的樹來說,從後往前搜尋那效率提公升的簡直令人難以想象!

而bfs呢,則是借助於佇列一層一層擴充套件,對於所有狀態都當且僅當遍歷到一次 由於「當且僅當一次」的原因,bfs在效率上還是非常高的(o(e)(邊數)) 尤其在平面圖上,特別形象,就如水波一般層層擴充套件出去 (注:實現佇列時可用類似滾動陣列的想法,由於先前擴充套件過的狀態往往沒什麼用了,便可以++tal%=tt重複利用。。環保)

一般來說,dfs適用於這類題目:

1、對遍歷順序有一定要求的。如要求遍歷序列字典序最小(poj2488),要求某某轉向優先(poj3083)……

2、狀態巨大、但層數有限,用bfs可能一層也擴充套件不完或標記不下(poj3009)

*特殊演算法:dfs序,tarjan縮點,二分圖匈牙利演算法……

而bfs呢:

最典型,無權圖或同權圖上刷最短路,其他如一些將a序列變換到b序列的最小步數、三水杯倒水之類的,轉換建模一下,還是個簡單的bfs(poj3083,poj3278,poj1426,poj3126,poj3 087,poj3414)

另外,像求聯通塊這類dfs/bfs兩者皆可的情況下——

dfs通常**簡短;但由於多次呼叫系統棧,速度相對較慢;在windows系統下,本地除錯也容易爆棧 (注:可在**前端加上「#pragma gcc optimize(2)」(o2優化)或在「工具–編譯選項–編譯時加入以下命令」欄中輸入「-wl,-stack=1000000000」來避免)

而bfs借助於佇列(陣列),速度自然要快一些,不過寫起來清陣列、給初始狀態、維護佇列之類的,也要繁瑣一些

總之,一句話,因題施法!

簡單搜尋 DFS BFS

1 dfs depth first search 深度優先搜尋演算法 是圖與樹搜尋中用到的一種演算法 遍歷的思想是 先從根部進行,一直遍歷到最底部的葉節點,然後再返回到根節點,判斷,如果該根節點上的葉節點都被遍歷過,再返回到根節點,直到遍歷到整棵樹。dfs遍歷循序 我們可以通過棧的思想來進行搜尋,a...

搜尋演算法 DFS BFS(簡單介紹)

一般步驟 1 把初始狀態放入陣列中,設為當前狀態 2 擴充套件當前的狀態,產生乙個新的狀態放入陣列中,同時把新產生的狀態設為當前狀態 3 判斷當前狀態是否和前面的重複,如果重複則回到上乙個狀態,產生它的另一狀態 4 判斷當前狀態是否為目標狀態,如果是目標,則找到乙個解答,結束演算法。5 如果陣列為空...

DFS BFS搜尋 題目

這篇博主寫的是圖的深搜 圖的dfs附 圖的深度優先遍歷 出處 一條魚 2011 12 26 include include struct node 圖頂點結構定義 typedef struct node graph 圖形的結構新型態 struct node head 9 圖形頂點陣列 int vis...