BFS廣度優先搜尋——入門
阿新 • • 發佈:2019-01-09
BFS——廣度優先搜尋
廣度優先搜尋是通過對圖的完全遍歷來達到要求的點的演算法。其對圖的遍歷是如同波浪一樣,每層按照制定的方式一層一層向下搜。
如:
5 |
5 | 4 | 2 | 5 |
5 | 2 |
4 | 2 | 3 |
4 | 2 | 3 | 4 |
4 |
1 | 4 | 1 | 1 | 2 |
6 | 7 | 5 | 3 | 4 |
在以3為起點進行bfs搜尋,搜尋方式是每次只搜其上下左右的數,找其中比(最開始的)起點小的數。第一次就只會搜尋到4(上),4(右),1(下),2(左),但是其中只有2和1滿足條件,於是會將2和1作為下一層的起點,然後繼續搜下去,直到不能再搜為止(在圖中有四層,分別由四種顏色表示)。我們通常用佇列來儲存每次需要判斷的起點,一開始3(紅)在佇列中,將3(紅)讀取後,把滿足情況的1,2(綠)加入佇列,依次類推。
由此我們可以將bfs看成是一棵倒著的樹,3(紅)為其根節點;2,1(綠)為其子節點,2,1(藍)又分別為2,1(綠)的子節點,2(粉)為1(藍)的子節點。
我們通過一道例題來了解bfs的具體程式碼:
hrbust 1143 泉水:
同部落格題解連結:
原題連結:
題意是讓你找出圖中所有能從起點到達的比起點高度低的地方個數。
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<queue> using namespace std; const int MAX = 1000; struct Point{ // 定義點的結構體 int x,y; }start,zhuan,number; int sum; int hang,lie; int mapp[MAX+9][MAX+9]; int gao[MAX+9][MAX+9]; int step1[4] = {1,0,-1,0}; int step2[4] = {0,1,0,-1}; int bfs(Point start) //起始點 { queue<Point> que; //將起時點壓入佇列 que.push(start); mapp[start.x][start.y] = 1; while(!que.empty()){ number = que.front(); // 讀出佇列的第一個元素進行下一層的判斷,直到這一層的元素都判斷完後才會開始下一層的判斷 que.pop(); for(int i = 0;i < 4;i++){ zhuan.x = number.x+step1[i]; // 得出取出元素的上下左右的座標 zhuan.y = number.y+step2[i]; if(zhuan.x<=hang && zhuan.x>=1 && zhuan.y<=lie && zhuan.y>=1 && mapp[zhuan.x][zhuan.y]!=1 && gao[start.x][start.y]>=gao[zhuan.x][zhuan.y]){ que.push(zhuan); //如果滿足則將其壓入佇列 mapp[zhuan.x][zhuan.y] = 1; sum++; } } } return sum; } void init() { memset(mapp,1,sizeof(mapp)); for(int i = 1;i <= hang;i++){ for(int j = 1;j <= lie;j++){ mapp[i][j] = 0; } } sum = 1; } int main() { while(scanf("%d%d%d%d",&hang,&lie,&start.x,&start.y) != EOF){ init(); for(int i = 1;i <= hang;i++){ for(int j = 1;j <= lie;j++){ scanf("%d",&gao[i][j]); } } printf("%d\n",bfs(start)); } return 0; }
可以看出,在該題中對數的計數只需在每次壓入佇列時,對計數器加一。bfs的優勢在於對有關層數的問題上速度比dfs更快,但是,bfs在層數越高得時候,時間會非常大,就需要進行剪枝操作。