BFS廣度優先搜尋演算法

2021-08-31 10:01:06 字數 3164 閱讀 9700

廣度優先搜尋(bfs)包含一下幾個關鍵點:

1.狀態

2.狀態轉移方式

3.有效狀態

4.佇列

5.標記

void bfs(起始點)

} } 隊列為空,廣搜結束;

}

看乙個例子:

說有一天公主被大魔王抓了,關進了乙個迷宮裡,需要你這位勇士去營救(當然成功了就自然是公升職加薪贏取白富美啦),這個迷宮以二維陣列的形式給出(暫定為5*5的迷宮)例:

[    0 1 0 0 0

0 1 0 1 0

0 0 0 0 0

0 1 1 1 0

0 0 0 1 0    ]

其中0表示這裡可以走,1表示這裡是堵牆不能走,每次只能往上下左右四個方向走乙個單位,迷宮入口為左上角,而公主在最右下角,問你是否能找到一條最短的路徑成功救出公主,如果能輸出其路徑(每乙個路徑以座標形式給出,如(0,0)),不能輸出-1。

廣度優先遍歷其實是對狀態的一種遍歷,這裡要搞清楚什麼是狀態。我們先想一下從第乙個點出發,可以往右、下走,然後如果往右走,又會延伸出往右、下走,我們用一棵樹來表示((1,2,3)表示x=1,y=2,路徑長度也可以叫時間為3)

乙個點加上乙個時間t便構成了乙個所謂的狀態,而廣度優先搜尋就是按層,一層一層的搜尋這些狀態,直到找到要求的狀態為止。

上圖還有地方需要修改,因為第二次到達的點所需要的時間肯定比第一次到達所需要的時間多,如上圖的(0,0,3),所以,我們設定乙個標記,凡是我們到達過的點,便不進行第二次的搜尋與延伸,這就是所謂的剪枝。這樣一來狀態的總數便等於a*b(a為總行數,b為總列數),只要這個時間複雜度在我們的接受範圍之內,我們便可以採用廣度優先搜尋。

狀態轉移是指,由乙個狀態可以延伸出其他的那些狀態,也就是可以往哪些地方走的問題。

說了這麼多,我們看一下**:

#include#include#includeusing namespace std;

int migong[5][5];//儲存迷宮

bool flag[5][5];//標記該點是否到達過

class stat

;int r[4][2] = ,,,

};//用於狀態擴充套件

stat* bfs()//返回終點狀態

}return start;

}int main()

stat* p = bfs();

stacks;//放入棧中,主要是為了讓其反序,不然從目標狀態找其父節點遍歷的話,是反的

while(p != null)

while(s.empty() == false)

return 0;

}

相信大家看了**也就理解的**不離十了,這裡說一下裡面佇列的作用,主要利用了佇列的先進先出的特性,當乙個狀態向四個方向擴充套件時,依此將其放入佇列中,再由這四個狀態繼續擴充套件,這樣佇列狀態的取出便是按照層次的順序,一層一層地遍歷,這才是廣度優先搜尋的關鍵。

挑戰任務

「綠盟杯」決賽完美落幕之後,賽事團隊組織去乙個風景優美的山區進行團建。由於人數眾多必須選擇一塊較大的場地。他們找到了一塊足夠大的地方,但是場地上卻散布著許多石頭,為了方便活動,必須把這些石頭挪開。現在我們假設整個場地是一塊矩形的地圖,地圖座標的橫縱座標均為非負整數,每個座標點上有乙個值:

0:代表無法從這個點通過1:代表這個點可以順利通過n(大於1):代表這個點上有乙個可以去除的石頭,而且石頭的大小是n程式設計要求

補全右側**區中的int getminiumsteps(vector> stones)函式,完成挑戰任務中提出的要求:按照石頭大小,從小到大依次移除場地中的石頭,返回最小的步數,如果無法移除所有的石頭就返回-1

函式引數說明如下:

vector> stones:場地中各個座標點的情況(vector[0][0]代表座標(0,0)),即0代表無法通過,1代表可以順利通過,大於1的正數代表存在乙個可以移除的石頭,且石頭的大小是該點的值。

測試說明

樣例1:

輸入:1,2,3

0,0,4

7,6,5

輸出:6

樣例2:

輸入:1,2,3

0,0,0

7,6,5

輸出:-1

#第三題

#include #include #include #include #include #include #include #include #include#includeusing namespace std;

class teambuilding );}}

sort(trees.begin(), trees.end());

int ans = 0;

for (int i = 0, cur_row = 0, cur_col = 0; i < trees.size(); i++)

return ans;

}private:

int next_step(vector>& forest, int sr, int sc, int er, int ec) );

vector> visited(m, vector(n, 0));

visited[sr][sc] = 1;

int step = 0;

vectordir = ;

while (!myq.empty()) );}}

}return -1;}};

廣度優先搜尋演算法

廣度優先搜尋 bfs 這個是第乙個研究的課題,廣度優先搜尋也叫寬度優先搜尋,英文為breadth first searth,開始看的時候一頭霧水,基本也能懂大致意思,但是還不是真正的理解,今天又仔細看看,大致理解上又更深了一層吧。下面來總結下,自己的一些體會,以及對它的獨到的理解。大的方面來說它是一...

廣度優先搜尋演算法

在深度優先搜尋中,深度越大的結點越先得到擴充套件。如果把它改為深度越小的結點越先得到擴充套件,就是廣度優先搜尋法。廣度優先搜尋演算法的基本思想 1 建立乙個空的狀態佇列ss 2 建立乙個空的狀態庫sb 3 把初始狀態s 0 存入佇列ss中 4 若佇列狀態是目標狀態,則搜尋成功,演算法執行中止。如該狀...

廣度優先搜尋演算法

看了下廣度優先搜尋演算法得定義為從乙個頂點開始,找到最短路勁,歸結為一種連通圖得遍歷策略 如果我們要求v0到v6的一條最短路 假設走乙個節點按一步來算 注意 此處你可以選擇不看這段文字直接看圖3 1 我們明顯看出這條路徑就是v0 v2 v6,而不是v0 v3 v5 v6。先想想你自己剛剛是怎麼找到這...