BFS
深度优先搜索会向着一个方向一直走,走到头为止,再退回去尝试其他路线,而广度优先搜索是在每个方向上都一步一步地走。
例如:
有一个
从初始点
再从$ V_1$ 出发,到达下一组位置
依次类推,直到所有能到达点都走过。
模拟这个过程,用队列比较合适
一开始只有初始节点在队列里:
找到
然后此时
然后再从前往后,依次枚举
int dis[1001][1001];//初始都是inf
q.push((node){x,y});//初始位置放入队列
while(!q.empty())
{
node now=q.front();//取队列的首部
int x=now.x,y=now.y;
q.pop();//删除队首
for(枚举走一步能到达的位置(tx,ty))
{
if(dis[tx][ty]!=inf) continue;
//如果这个位置已经被走到过了,那么不可能比dis[x][y]+1还远,因为之前枚举到的点的dis不大于dis[x][y]
dis[tx][ty]=dis[x][y]+1;//更新到这个点的最短距离
q.push((node){tx,ty});//把(tx,ty)放入队列。
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
这样可以做到每个点得到的都是最短距离,因为我们相当于是先得到了所有走一步能到达的位置,然后再从所有走一步能到达的位置出发,到达所有走两步能到达的位置,以此类推。
根据这个算法,在任意时刻,队列里的点距离起点的距离之差不超过
假设队列前一半距离是
根据这个性质,也不会发生距离为
双向搜索
搜索树的节点个数并不是线性增长的,比如一个节点可以有两个子节点,那么规模为
如果我们可以每次搜一半的数据,然后将两部分拼起来,那么就会变成
比如上述问题,如果我们知道起点和终点,想问从起点走到终点至少需要多少步?
可以从起点和终点同时开始
我们用
练习题
P1596 [USACO10OCT] Lake Counting S