這個部分的知識點已經學過去很長時間了(???),但是由於沒有經過統一標準的學習,總感覺自己並不是完全地掌握這一些東西,所以打算回顧一下,也是爲了NOIP裏的分值(騙分)做準備qwq,畢竟考完就退役了qwq
本文基於此文qwq https://www.jianshu.com/p/1fc63ab1bcc2
基本思想
先選擇某一種可能的情況向前探索,在探索過程中,一旦發現原來的選擇是錯誤的,就退回一步重新選擇,繼續向前探索,如此反覆進行,直到得到解或證明問題無解。
普通的搜索
有兩種框架:
int search(int x) { for(int i=1;i<=...;i++) { if(滿足條件) { 保存結果; if(到目的地) 輸出解答; else search(x + 1); 回溯:恢復之前的狀態; } } } int search(int x) { if(到目的地) 輸出; else for(int i=1;i<=...;i++) { if(滿足條件) { 保存結果; search(x + 1); 回溯:恢復之前的狀態; } } }
這就象徵了一個不斷修正前進的過程
BFS
bfs就類似於一層一層地向下搜索,開始下一層搜索的充要條件是本層一定全部搜索過一遍
然後就不斷地向上傳遞自己下面的信息,從而達到每一個點都遍歷過的過程
框架:
q.push(Start);//1,將起點推入隊列中; vis[Start] = true;//2,將起點標識爲已走過; while(q.empty())//(隊列非空) { int vt = q.top();//3,取隊列首節點vt,並從隊列中彈出; for(int i=head[vt];i;i=edge[i],next)//4,探索上面取出得節點的周圍是否有沒走過的節點vf { if(...) Node[vt].parent = Node[vf].parent }//如果有將所有能走的vf的parents(information)指向vt,並將vf加入隊列 if(vf == Finish) return vf;//(如果vf等於終點,說明探索完成,退出循環)。 } return -1;//如果隊列爲空自然跳出,說明無路可達終點
DFS
一般來說DFS都是最常用的一種,在遍歷樹的時候一般都會優先選擇DFS(很多以BFS爲基礎的算法也有關於DFS的優化,而且往往很優)
DFS就是在一個節點搜索徹底(不能再向下)之後再去回溯到上一個狀態再進行徹底地搜索,最終找到最優答案
框架:
1,棧初始化 2,獲得起點,將起點標識爲已走過,將起點入棧 while(棧非空){ 取棧頂元素vt 如果vt周圍有爲走過的節點vf,則: 將vf改爲已走 vf入棧 沒有能走的節點,vt出棧 }