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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM