这个部分的知识点已经学过去很长时间了(???),但是由于没有经过统一标准的学习,总感觉自己并不是完全地掌握这一些东西,所以打算回顾一下,也是为了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出栈 }