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 泉水:
同博客题解链接:
http://blog.csdn.net/ilblue/article/details/52892373
原题链接:
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=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在层数越高得时候,时间会非常大,就需要进行剪枝操作。