深度优先搜索(DFS)
适用范围
深度优先搜索适合解决必须走到最深处(例如对于树,须走到它的叶子节点)才能得到一个解的问题。通常利用递归实现,所以每次递归开始的时候要判断是否达到收敛条件,若达到了则得到一个可行解,若没达到,则对当前状态进行扩展(扩展的时候通常会根据实际情况过滤掉一些非法的状态,这个过程叫剪枝,适当的剪枝有时能极大地提高搜索的速度),如果要求输出具体解,则此时应该保存该状态,当扩展结束后,需要释放这个保存的状态。下面是一个深度优先搜索的编程模板:
核心代码
/**
* dfs 模板.
* @param[in] input 输入数据指针
* @param[inout] cur or gap 标记当前位置或距离目标的距离
* @param[out] path 当前路径,也是中间结果
* @param[out] result 存放最终结果
* @return 路径长度,如果是求路径本身,则不需要返回长度
*/
void dfs(type *input, type *path, int cur or gap, type *result) {
if (数据非法) return 0; // 终止条件
if (cur == input.size( or gap == 0)) { // 收敛条件
将 path 放入 result
}
if (可以剪枝) return;
for(...) { // 执行所有可能的扩展动作
执行动作,修改 path
dfs(input, step + 1 or gap--, result);
恢复 path
}
}
dfs(v){
if(v是旧点){
return;
}
将v标记为旧点
对和v相邻的每个点u{
dfs(u);
}
}
int main(){
将所有点都标记为新点;
while(在图中能找到新点k){
dfs(k);
}
}