WJX博客

学习笔记——双向搜索

前言

双向搜索是对搜索的一个优化技巧,通过这个技巧我们可以使搜索的复杂度减半(\(O(2^n)\)变为\(O(2 \times 2^{\frac{n}{2}})\))。

算法

在已知搜索起点和终点的情况下,我们可以同时从起点和终点进行搜索,最后两端搜索相遇的地方就是答案。

如上图所示,我们同时从起点(\(1\))和终点(\(15\))开始搜索,就可以较快的搜索到最终答案(\(8\))。

例题

P1379 八数码难题(题解)(我的代码)

本题是双向搜索的入门题,我们可以同时将起点和终点压入队列中,用vis[] 数组记录节点是先被起点搜索到还是先被终点搜索到,用ans[]数组记录搜索的步数,最后把第一个被起点和终点搜索到的节点所用步数相加即为答案。

P2324 [SCOI2005]骑士精神(题解)(我的代码)

本题需要我们运用状压的思想,将棋盘的马的位置压缩成字符串,用map存储后即可进行双向搜索。

P4799 [CEOI2015 Day2]世界冰球锦标赛(题解)(我的代码)

本题我们可以给dfs 限制一定的层数,使每一次dfs仅搜索一半的比赛,最后整合答案即可。

P3067 [USACO12OPEN]Balanced Cow Subsets G(题解)(我的代码)

在本题中,我们用\(01\)\(i\)个数是否被选用,最后统计有多少个不重复的\(01\)串即可。

P5691 [NOI2001] 方程的解数(题解)(我的代码)

我们可以分别搜索前三个和后三个位置,将范围内所有的数遍历一遍,在和饼干两次搜索的结果即可。

CF888E Maximum Subsequence(题解)(我的代码)

本题我们可以分别求出前半段和后半段之和模\(m\)的值域,用两个指针分别从两个值域的一头一尾开始移动,直到a[i]+b[j]<m时更新答案。

CF1006F Xor-Paths(题解)(我的代码)

因为从\((1,1)\)\((n,m)\)的步数是一定的,所以我们可以分别从起点和终点走到x+y==(m+n/2+1)的位置,统计答案即可。(\(PS\)因为x+y==(m+n/2+1)的位置走了两次,所以最后还要异或该位置的值统计答案)

P2962 [USACO09NOV]Lights G(我的代码)

在本题中,我们可以用一个数组记录选第\(i\)个点时会改变的节点集合(该数组存储一个二进制数,会改变的节点集合在该二进制位上为\(1\)),双向搜索时选择该点就将答案异或数组中该点对应的值,最后统计异或后所有二进制位为\(1\)的最小选择节点数。

posted @ 2021-09-26 15:22  WJX3078  阅读(446)  评论(0)    收藏  举报