广度优先搜索一般由队列实现,且总是按层次的顺序进行遍历,基本写法如下:
void BFS(int s){
queue<int> q;
q.push(s); //定义一个队列q,并将起点s入队
//队列q非空
while(!q.empty()){
取出队首元素top;
访问队首元素top;
将队首元素出队;
将top的下一层结点中未曾入队的结点全部入队,并设置为已入队; //标记层号为now的层号+1,同时设置这些入队的结点已入队
}
}
例题1
给出m×n的矩阵,矩阵中的元素为0或1,称位置(x,y)与其上下左右四个位置是相邻的。如果矩阵中有若干个1是相邻的(不必两两相邻),那么称这些1构成了一个块,求给定矩阵中块的个数。
输入:
6 7
0 1 1 1 0 0 1
0 0 1 0 0 0 0
0 0 0 0 1 0 0
0 0 0 1 1 1 0
1 1 1 0 1 0 0
1 1 1 1 0 0 0
块的个数为4
思路
枚举每一个位置的元素,如果为0,则跳过;如果为1,则使用BFS查询与该位置相邻的4个位置(前提是不出界),判断他们是否为1,如果某个相邻的位置为1,则同样去查询与该位置相邻的4个位置,直到整个1块访问完毕。为了防止走回头路,可以设置一个bool型数组inq来记录每个位置是否在BFS中已入过队。
对当前位置(x,y)来说,与其相邻的四个位,置分别为(x,y+1),(x,y-1),(x+1,y),(x-1,y),那么不妨设置下面两个增量数组,来表示四个方向:
int X[]={
0,0,1,-1};
int Y[]={
1,-1,0,0};
这样就可以用for循环来枚举四个方向,以确定与当前坐标(nowX,nowY)相邻的4个位置:
for(int i=0;i<4;i++){
newX=nowX+X[i];
newY=nowY+Y[i];
}
代码
#include <stdio.h>
#include <queue>
using namespace std;
const int maxn=100;
struct node{
int x,y;
}Node;
int m,n; //矩阵大小为 n×m
int matrix[maxn][maxn]; //01矩阵
bool inq[maxn][maxn]={
false}; //记录位置x,y是否已入过队
//增量数组
int X[]={
0,0,1,-1};
int Y[]={
1,-1,0,0};
//判断坐标x,y是否需要访问
bool judge(int x,int y){
//越界返回false
if(x>=n||x<0||y>=m||y<0)