一、關於DFS
1. 什么是DFS
深度優先搜索算法,又稱DFS(Depth First Search)。DFS算法是一種搜索算法,而搜索算法實質上是一種枚舉,即借助計算機的高性能來有目的地枚舉一個問題的部分情況或這個問題的所有情況,進而求出問題的解的一種方法。
2. DFS的搜索方式
根據算法的名字,我們很容易知道DFS是按照深度優先的順序對所有的狀態進行搜索的。
DFS算法是遞歸算法的一種。搜索時沿着樹的深度遍歷樹的節點,並盡可能深地搜索樹的分支(到葉子節點為止)。當節點v的所有邊都被訪問過時,搜索將回溯到發現節點v的那條邊的起始節點。搜索過程一直進行到已發現從源節點可達的所有節點全部被訪問為止。
二、DFS的具體實現
搭建一個dfs程序並不困難,真正值得我們注意的是dfs算法的剪枝部分。dfs的剪枝方法因題而異,但歸類后大概分為5類。這一點我們稍后會提及。
這里給出一般dfs的框架:
void DFS(type n){ //可以描述階段的狀態
if(符合條件) {cout<<答案;return;} //出口
if(可以剪枝) return; //剪枝
for(i:1~p){ //選擇該階段的所有決策
選擇可行決策; //剪枝的一種
標記已訪問該點;
DFS(n+1); //進入下一階段
(還原訪問現場;)
}
}
三、剪枝
剪枝分為以下5類:
1. 順序性剪枝
若一些題的搜索順序對答案無影響,那么搜索順序的不同會導致搜索樹形態的改變,優先搜索分支較少的階段,此時能減少搜索的規模。
2. 重復性剪枝
在搜索的時候如果有多種方式可以到達一個狀態,那么我們只需要搜索一個分支就可以了。
3. 可行性剪枝
可行性剪枝是對搜索正確性的一個保證,當分支在遞歸邊界的時候回溯。
4. 最優性剪枝
在搜索過程中,如果當前階段的代價已經超過我們已知的最小代價,那么此時繼續搜索下去就失去了意義。
5. 記憶化剪枝
記錄搜索狀態的結果,當重復遍歷一個狀態的時候就可以直接返回這個狀態的答案,避免重復的搜索。
四、練習
- P1025 數的划分
- P1034 矩形覆蓋
- P1074 靶形數獨
- P1784 數獨
- P1092 蟲食算
- P2329 (SCOI2005)柵欄
- P1220 關路燈
- P2668 斗地主
- P1731 (NOI1999)生日蛋糕
- P1120 小木棍