算法笔记 BFS

这个是题目:相当于就是输入一个只有01的矩阵,求其中1的块数

思路:这道题其实也就是求连通块的问题,只要一个位置的上下左右中存在一个1那就可以连通到一起,是BFS经典的题目

#include<stdio.h>
#include<string.h>
//#include <stdbool.h>
#include <algorithm>
#include<queue>
using  namespace std;
//这里需要创建一个结构体 在BFS中能用到
struct node{
    int x;
    int y;
}Node;
int n,m;//对应数组的行和列
//BFS
//前期准备就是,需要一个01矩阵,两个增量数组,一个判断是否访问过的访问数组
int jv[100][100]={0};
bool  flag[1000][1000]={false};//默认是没有访问过
int XX[4]={0,0,1,-1};
int YY[4]={1,-1,0,0};//用来for循环的,分别对应四个位置

//需要写一个方法来判断当前位置需不需要访问
bool  judge(int x,int y){
    //第一种不需要访问的情况,数组越界
    if(x<0||x>n-1||y<0||y>m-1)
    return  false;
    //第二种情况,就是位置是第一个或者已经被访问过了的(其实位置是第一个也算是已经被访问过的其中一个)
    if((x==0&&y==0)||flag[x][y]==true){
            return false;
    }
    return true;
    }
//开始写BFS,首先是需要有一个队列,其次便是不需要递归
void BFS(int x,int y){
     queue<node> q;//创建一个队列,说明这个队列是Node类型的
     //对位置设置成访问过了
     Node.x=x;
     Node.y=y;
     flag[x][y]=true;
     //进队列
     q.push(Node);
     while(!q.empty()){//如果队列非空的话
            //先取出队头,先把对头元素记录下来
            node top =q.front();//这里的top其实就是之前的Node
            q.pop();//对头元素出队
            //开始判断周围的四个
            int i;
            for(i=0;i<4;i++){
                int Newx=top.x+XX[i];//这里改正了一下,数组方面以免引起歧义
                int NewY=top.y+YY[i];
                //如果没被访问过,并且值等于1的话,就进队,并把访问位标记
                if(jv[Newx][NewY]==1&&judge(Newx,NewY)==true){
                    Node.x=Newx;
                    Node.y=NewY;
                    q.push(Node);
                    flag[Newx][NewY]=true;
                }

            }
     }

}
int main()
{

    //到主函数,就需要先设置矩阵
    scanf("%d%d",&n,&m);
    int i,j;
    for(i=0;i<n;i++){
        for(j=0;j<m;j++){
        scanf("%d",&jv[i][j]);
        }
    }
    printf("%d\n",jv[0][0]);
    int sum=0;//用来记录最后的值
    //就是开始遍历,从第一个等于1的地方开始,sum++,然后深度遍历其他地方
    for(i=0;i<n;i++){
        for(j=0;j<m;j++){
            if(jv[i][j]==1&&flag[i][j]==false){//第一个位置
                sum++;
                BFS(i,j);//把与他有关的,都遍历设置过去

            }
        }
    }
    printf("%d\n",sum);
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值