BFS寬度優先搜索(新冠病毒的傳播)

應該是我博客的第一篇廣度優先搜索的算法了吧,之前題目都用的DFS,因爲DFS確實比較熟練點,BFS雖然很久之前就知道他是怎麼實現的但是沒怎麼自己真正實踐過~~~而且以前一聽隊列就頭大,不過最近這方面需求還挺大的-.-
文章首發

寬度優先搜索
(Breadth First Search)

寬度優先搜索算法(又稱廣度優先搜索)是最簡便的圖的搜索算法之一,這一算法也是很多重要的圖的算法的原型。Dijkstra單源最短路徑算法和Prim最小生成樹算法都採用了和寬度優先搜索類似的思想。其別名又叫BFS,屬於一種盲目搜尋法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。換句話說,它並不考慮結果的可能位置,徹底地搜索整張圖,直到找到結果爲止。

簡單的說應該就是,搜索當前可以到達的地方,壓入隊列,然後再取首元素,再查找,繼續壓入隊列,與DFS有什麼不同呢:把兩個搜索比作探案,DFS就像是先摸着一個線索,然後深究到最後,如果不通再返回,查看有沒有其他錯過的東西,而BFS就像有邏輯的偵探,先找到能找到的所有線索,把它們收集起來,然後再一個個撥開,把它們後面的線索再收集起來。

在這裏提供一個模板

迷宮題型
void bfs(){
    起點入隊    //迷宮題用結構體存X,Y
    while(隊列不爲空){
        當前點 = queue.front();             //取出隊首元素
        for(四個方向){
            xx=x+上下左右
            yy=y+上下左右
            if(判斷X,y有無越界){
                continue;
            }
            if(如果能走){
                結構體 k;
                queue.push(k);
                標記
            }
        }
    }
}

推薦

正月點燈籠:BFS講解
如果有時間的話可以看下上面這個博主的視頻,很久以前關注的,這個真的講的很形象~~


來道例題

題目

最近新冠病毒疫情非常嚴重,由於我們國家採取了有力的措施,纔沒有使疫情進一步的擴大。今天,作爲計算機專業的學生,我們來用程序模擬一下各種情況下的新冠病毒傳播情況。現在給定一個n * m的網格,每個網格可以有以下三個值之一:
值 0 代表隔離帶。
值 1 代表健康人羣。
值 2 代表感染人羣。
每天,任何與感染人羣(在 4 個正方向上)相鄰的健康人都會感染。如果遇到隔離帶,病毒就會被阻斷。
輸出直到單元格中沒有健康人爲止所必須經過的最小天數。如果不可能所有人都被感染,輸出 -1。

輸入

測試數據由多組測試樣例組成。第一行輸入兩個正整數 n ( 1 <= n <= 500 ) 和 m ( 1 <= m <= 500 ),
接下來輸入n * m個數字,數字均由 0 , 1 ,2構成

輸出

每組測試樣例,輸出直到單元格中沒有健康人爲止所必須經過的最小天數。如果不可能,輸出 -1。

樣例輸入

3 3
2 1 1
1 1 0
0 1 1
3 3
2 1 1
0 1 1
1 0 1
1 2
0 2

樣例輸出

4
-1
0

代碼

#include<bits/stdc++.h>
using namespace std;
int dir[4][2]={0,1,1,0,-1,0,0,-1};
int Map[1000][1000];
int qx;
int qy;
int n,m,sum;
struct fun{
	int x;
	int y;
	int t;
}great;
queue<fun> q;
void bfs(){
	while(q.size()){
		fun num= q.front();	//取出
		if(num.t>sum)
			sum=num.t;
		q.pop();
		for(int i=0;i<4;i++){
			int xx=num.x+dir[i][0];
			int yy=num.y+dir[i][1];
			if(xx<0||xx>n||yy<0||yy>m){	//越界 
				continue;
			}
			if(Map[xx][yy]!=0&&Map[xx][yy]!=2){	 
				fun k;
				k.x=xx;
				k.y=yy;
				k.t=num.t+1;
				q.push(k);
				Map[xx][yy]=2;
			}
		}
	}
}
int main(){
	while(scanf("%d %d",&n,&m)!=EOF){
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				scanf("%d",&Map[i][j]);
				if(Map[i][j]==2){
					great.x=i;		//當前座標 
					great.y=j;
					great.t=0;
					q.push(great);		//起始點壓入 
				}
			}
		}
		sum=0;
		bfs();
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(Map[i][j]==1){
					sum=-1;
				}
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章