上次講的dfs是一直往前走,直到無路可走的時候就返回,而bfs不一樣。
bfs是廣度優先搜尋,顧名思義就是橫著來搜尋,也就是按層次來搜尋,一層層來搜尋。
廣度優先搜尋是一種分層的查詢過程,每向前走一步可能訪問一批頂點,不像深度優先搜尋(dfs)那樣有回退的情況,因此它不是乙個遞迴的演算法,為了實現逐層的訪問,演算法必須借助乙個輔助佇列並且以非遞迴的形式來實現。
bfs搜尋的步驟
1、首先建立乙個mp[ ]陣列用來判斷該位置是否被訪問;
2、再建立乙個佇列p用來儲存下一步要訪問的點。
3、讓起點start入隊,並使該點的mp賦值為1;
模板
struct node
;//結構體
queuep;//佇列p
int mp[10005][10005];
int dx=;//方向陣列
int dy=;
// 計算從起點 start 到終點 ed 的最近距離
int bfs(node start, node target) );//將xx,yy,temp.step+1,當成結構體壓入佇列
mp[xx][yy]=1;//標記走過}}
}
這是乙個關於二維迷宮的題目。我們要從迷宮的起點 『s』 走到終點 『e』,每一步我們只能選擇上下左右四個方向中的乙個前進一格。 『w』 代表牆壁,是不能進入的位置,除了牆壁以外的地方都可以走。迷宮內的 『d』 代表一道上鎖的門,只有在持有鑰匙的時候才能進入。而 『k』 則代表了鑰匙,只要進入這一格,就會自動地拿到鑰匙。最後 『.』 則是代表空無一物的地方,歡迎自在的遊蕩。
本題的迷宮中,起點、終點、門跟鑰匙這四個特殊物件,每乙個恰好會出現一次。而且,此迷宮的四周 (最上面的一行、最下面的一行、最左邊的一列以及最右邊的一列) 都會是牆壁。
請問,從起點到終點,最少要走幾步呢?
輸入的第一行有兩個正整數h, w,分別代表迷宮的長跟寬。
接下來的h行代表迷宮,每行有乙個長度恰為w的字串,此字串只包含`'s'`, `'e'`, `'w'`, `'d '`, `'k'`, `'.'`這幾種字元。
請在一行中輸出乙個整數代表答案,如果無法從起點走到終點,請輸出-1。
示例1
4 12
wwwwwwwwwwww
we.w.s..w.kw
w..d..w....w
wwwwwwwwwwww
20
示例2
6 6
wwwwww
wews.w
w.wk.w
w.wd.w
w.w..w
wwwwww
-1
4 ≤ h, w≤ 500
's', 'e', 'k', 'd'各出現恰好一次
迷宮的四周(最上面的一行、最下面的一行、最左邊的一列以及最右邊的一列) 都會是 'w'
思路
從起點到終點一共存在兩種可行性
1)起點直接到達終點, 起點 -> 終點。
2)通過 起點s -> 鑰匙 -> 門-> 終點e。
最終到達終點的可行方案
1)如果不能直接從 起點s -> 終點e,需要考慮獲取鑰匙開門的途徑,如果仍然不能到達終點,則輸出 -1,否則輸出到達終點的最小步數。
2)如果起點s -> 終點e 可行,那麼獲取鑰匙開門到達終點必定可行,此時只需比較二者步數,獲得最小步數即可。
#includeusing namespace std;
int mp[505][505];//用來標記該點是否被走過
char migon[505][505];//輸入
int dx = ;
int dy = ;
int h,w;
struct car
st,ed,key,door;//定義起點,終點,鑰匙,門,四個結構體;
int bfs(car beg,car end)
} return -1;
} int main()
} memset(mp,0,sizeof(mp));
int ans1=bfs(st,ed);//直接從起點到終點,不開門
memset(mp,0,sizeof(mp));
int ans2=bfs(st,key);//從起點去拿鑰匙
memset(mp,0,sizeof(mp));
migon[door.x][door.y]='.';//拿到鑰匙將門變成點
int ans3=bfs(key,door);//拿了鑰匙去開門
memset(mp,0,sizeof(mp));
int ans4=bfs(door,ed);//開完門去終點
if(ans1==-1)//不拿鑰匙走不通的情況
;int dy=;
struct car
;queuep;
int bfs()
p.push();}}
}}int main()
);//將每個店當起點壓入佇列
} for(int i=1;i<=k;i++)
for(int i=1;i<=d;i++)
cout<
題目描述
有乙個n×
\times
×m的棋盤(1一行四個資料,棋盤的大小和馬的座標
輸出格式
乙個n×
\times
×m的矩陣,代表馬到達某個點最少要走幾步(左對齊,寬5格,不能到達則輸出-1)
輸入3 3 1 1
輸出
0 3 2
3 -1 1
2 1 4
#includeusing namespace std;
int n,m,x,y;
int dx=;
int dy=;
int mp[1005][1005];
int a[1005][1005];//用來記錄起點到每乙個點的步數
struct car
;queuep;
void bfs(car st)
); a[xx][yy]=a[temp.x][temp.y]+1;
} }}
int main()
); for(int i=1;i<=n;i++)
cout<} return 0;
}
BFS例題 A計畫
c ontr ibcontrib a11y accessibility menu.js 關於 bfs要點 1 若為可化為的座標系圖形,可用結構體儲存其x值,y值和步數。一般開now 和 next now用於取出佇列裡面的結構體 next用於上下左右的運動計算,並且push到佇列中。2 在運用佇列時,...
BFS基礎例題
都是kuangbin的題 例1 poj2251 dungeon master 三維迷宮問題 題目大意 在三維空間中給出起點和終點,找最短的逃出去的路徑長 做法 bfs基礎上增加一維,本質是一樣的 const int maxn 2e6 7 const int inf 1e9 const ll inff...
bfs思路總結
1 將初始狀態加入佇列 2 初始狀態出隊,進行節點擴充套件。可能是狀態轉移,列出狀態轉移方程 3 在進行擴充套件中,需要判斷節點不要重複擴充套件。基本思路是設立visited陣列,標記狀態是否被訪問過。將狀態用乙個整數表示,整數則可以是陣列下標,該陣列下標對應的陣列元素的值即是狀態是否被訪問的標誌。...