zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    day02-数据库操作
    day01-MySQL介绍
    3-socketserver
    1-多线程与多进程
    keyword模块
    math模块
    查看进程pid与ppid
    开启进程的两种方式
    进程理论
    进程
  • 原文地址:https://www.cnblogs.com/StungYep/p/12252357.html
Copyright © 2011-2022 走看看