BFS(广度优先搜索)

BFS(广度优先搜索)

最简单的搜索包含 DFS 和 BFS,他们分别有着下面不同的用途和区别:

区别于用途:

1.BFS是用来搜索最短径路的解是比较合适的,比如求最少步数的解,最少交换次数的解,因为BFS搜索过程中遇到的解一定是离根最近的,所以遇到一个解,一定就是最优解,此时搜索算法可以终止。这个时候不适宜使用DFS,因为DFS搜索到的解不一定是离根最近的,只有全局搜索完毕,才能从所有解中找出离根的最近的解。(当然这个DFS的不足,可以使用迭代加深搜索ID-DFS去弥补)

2.空间优劣上,DFS是有优势的,DFS不需要保存搜索过程中的状态,而BFS在搜索过程中需要保存搜索过的状态,而且一般情况需要一个队列来记录。

3.DFS适合搜索全部的解,因为要搜索全部的解,那么BFS搜索过程中,遇到离根最近的解,并没有什么用,也必须遍历完整棵搜索树,DFS搜索也会搜索全部,但是相比DFS不用记录过多信息,所以搜素全部解的问题,DFS显然更加合适。

下面是广度优先搜索的基本思想与模板

BFS用到了队列的一些操作,其基本思想步骤是:

1.首先将根节点放入队列中。

2.从队列中取出第一个节点,并检验它是否为目标。

3.如果找到目标,则结束搜索并回传结果。否则将它所有尚未检验过的直接子节点加入队列中。若队列为空,表示整张图都检查过了——亦即图中没有欲搜索的目标。结束搜索并回传“找不到目标”。

4.重复步骤2。

其基本模板如下:

初始化队列Q
Q={起点s};
标记s为已访问
while(!Q.empty())
{
    去Q队首元素U;
    u出队;
    if(u==目标状态){...}
    所有与u相邻且未访问过的点进入队列;(可以通过设一个方向数组for一遍实现)
    标记U为已访问;
}

一个完整的程序如下:

#include<iostream>
#include<queue>
#include<cstring>

using namespace std;
const int maxn=2e5+5;
int v[maxn];
int n,k,t,ans[maxn];
queue<int> q;
void bfs(int start,int last)
{
    q.push(start);
    int fi,ne;
    ans[start]=0;
    v[start]=1;
    while(!q.empty())
    {
        fi=q.front();
        q.pop();
        for(int i=0; i<3; ++i)
        {
            if(0==i)    ne=fi-1;
            else if(1==i)   ne=fi+1;
            else if(2==i)   ne=fi*2;
            if(ne<0||ne>maxn)   continue;
            if(!v[ne]){
                q.push(ne);
                v[ne]=1;
                ans[ne]=ans[fi]+1;
            }
            if(ne==last)    break;
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>k;
    memset(v,0,sizeof(v));
    memset(ans,0,sizeof(ans));
    bfs(n,k);
    n>=k?cout<<n-k<<endl:cout<<ans[k]<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/StungYep/p/12252357.html