广度优先搜索(BFS)
廣度優(yōu)先
Description:
阿貍被困在迷宮,snoopy要去救他,snoopy可以向上、下、左、右四個方向行走,每走一步(格)就要喝掉一瓶益力多。現(xiàn)在給它一個迷宮地圖請問:snoopy最少需要多少瓶益力多才能走出迷宮?
Input:
先輸入一個數(shù)t,表示測試的數(shù)據(jù)個數(shù), 下面輸入的就是t個迷宮, 每個迷宮的輸入都應(yīng)包含以下數(shù)據(jù), 輸入迷宮的大小 n(n<=15),表示迷宮大小為n*n。 再輸入迷宮, 用大寫字母“S”表示snoopy的位置, 用小寫字母“E”表示阿貍被困的位置, 用“.”表示空白, 用“*”表示障礙, 你知道的阿貍和snoopy都只有一個。
Output:
輸出需要的最少的益力多的瓶數(shù)m(數(shù)據(jù)保證一定有最少需要的利益多的瓶數(shù)) Sample Input:2
8
S..*....
.*...**.
..*.**..
.*..*..*
*..*E.**
........
.***..*.
....*...
8
S..*....
.*...**.
.**.**..
.*..*..*
*..**.**
........
.***..*.
....*..E
Sample Output:
12
16
?
題意分析:這題是最簡單的求最短距離的題目,也就是典型的BFS問題。
廣度優(yōu)先搜索:http://baike.baidu.com/view/288267.htm 如果不想看這么長的文字解釋,可以看一下下面的PPT:http://www.docin.com/p-542536008.html?
下面繼續(xù)分析這道題目,我們挑選第二組數(shù)據(jù)進(jìn)行分析。首先,我先把數(shù)據(jù)從數(shù)組下標(biāo)為[1][1]的地方開始存儲。讓后在地圖的周圍“造”一堵墻(如圖1)。我們還需要開一個跟地圖一樣大的數(shù)組visit來記錄已經(jīng)走過的點。將所有點初始化為0,走過的點記為1。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ?圖1 圖2 圖3
?然后記錄S的坐標(biāo)。將S入隊并標(biāo)記visit[s.x][s.y]=1,查看S點是否等于E,不等,將隊首元素pop出去;否則返回結(jié)果。然后查看與S相鄰的上下左右4點(上下左右的順序隨便),如果該點不是墻(即'*')并且之前沒走過(visit[該點.x][該點.y]等于0),則將該點入隊,標(biāo)記visit[該點.x][該點.y]=1;否則不做處理。相鄰的點都查看完后,再取隊首元素查看該點是否等于E.......(重復(fù)做綠色部分的步驟,直到隊列為空)。為了便于理解,上面貼出了圖2和圖3。圖中的數(shù)字即為第n步到達(dá)的位置。
下面貼出源代碼:
?
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 using namespace std; 5 char map[17][17];//地圖 6 bool visit[17][17];//用來記錄狀態(tài) 7 int dir[][2]={{1,0},{0,1},{-1,0},{0,-1}};//方向 8 struct Point 9 { //記錄點的坐標(biāo)和步數(shù) 10 int x,y,cnt; 11 }; 12 void BFS(int sx,int sy) 13 { 14 queue<Point> a; 15 Point now,next; 16 now.x = sx; now.y = sy; now.cnt = 0; 17 a.push(now); 18 visit[sx][sy] = 1; 19 while(!a.empty()) 20 { 21 Point temp = a.front(); a.pop(); 22 if(map[temp.x][temp.y] == 'E') 23 { 24 printf("%d\n",temp.cnt); 25 return ; 26 } 27 for(int i = 0; i < 4; i++) 28 { 29 next.x = temp.x+dir[i][0]; 30 next.y = temp.y+dir[i][1]; 31 next.cnt = temp.cnt+1; 32 if((!visit[next.x][next.y]) && (map[next.x][next.y]!='*')) 33 { a.push(next); visit[next.x][next.y] = 1;} 34 } 35 } 36 return ; 37 } 38 int main(void) 39 { 40 int i,j,t,m,n; 41 scanf("%d",&t); 42 while(t--) 43 { 44 int sx,sy; 45 memset(visit,0,sizeof(visit)); 46 scanf("%d",&n); 47 for(i = 1; i <= n; i++) 48 scanf("%s",&map[i][1]); 49 for(i = 0; i <= (n+1); i++) 50 for(j = 0; j <= (n+1); j++) 51 { 52 if(map[i][j] == 'S') 53 sx = i, sy = j; 54 if((i==0) || (j==0) || (i==n+1) || (j==n+1)) 55 map[i][j] = '*'; 56 } 57 BFS(sx,sy); 58 } 59 60 return 0; 61 } View Code?
這是我做的第一道搜索題,做了一下午,才真正搞懂BFS。以前也一直不會BFS,看別人的代碼都好長,有的又看不懂。還是上面紅色鏈接里的PPT幫了大忙,不懂的多看幾次PPT。下面是我做的PPT也可以看看:http://files.cnblogs.com/files/Muia/%E8%BF%B7%E5%AE%AB.ppt
?
轉(zhuǎn)載于:https://www.cnblogs.com/Muia/p/5774317.html
總結(jié)
以上是生活随笔為你收集整理的广度优先搜索(BFS)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【动态规划】Vijos P1313 金明
- 下一篇: 详解--单调队列 经典滑动窗口问题