求连通块数量模板 (BFS)

连通块模板(BFS)

大致思路就是选中一个点然后向四周拓展并标记,如果不能拓展了就为一个块,最后输出个数即可

复制代码
#include<iostream>
#include<queue> // 利用队列存储数据
using namespace std;
int n, m, cnt ; // 全局变量默认为0
int arr[105][105] ;
int book[105][105] ;
int dx[] = {-1, 0, 1, 0} ; // 利用两个一维数组来表示四个方向
int dy[] = {0, 1, 0, -1} ;
struct node 
{
	int x ;
	int y ;
};
queue<node> qu ;  // 建立一个存放结构体的队列
void bfs(int x1, int y1) // 传入起点坐标
{
	node a = {x1, y1} ;
	qu.push(a) ; // 把起点存入队首
	while (!qu.empty()) //队列非空是循环条件
	{
		node b = qu.front() ; // 取出队首
		qu.pop() ; // 去掉队首
		for (int i = 0 ; i < 4 ; i++) { // 利用循环遍历四个方向
			int nx = b.x + dx[i] ;
			int ny = b.y + dy[i] ;
			if (nx < 0 || nx > n - 1 || ny < 0 || ny > m - 1) continue ; // 判断边界
			if (arr[nx][ny] == 0 && book[nx][ny] == 0) { 
				book[nx][ny] = 1 ; // 把可拓展的地方标记起来
				node c = {nx, ny} ;
				qu.push(c) ;
			} // 如果四周没有可以拓展的地方,就会不断弹出队首,直到队列为空跳出循环
		}
	}	
}
int main(void)
{
	cin >> n >> m ;
	for(int i = 0 ; i < n ; i++) { // 读入二维数组
 		for (int j = 0 ; j < m ; j++) {
 			cin >> arr[i][j] ;
 		}
	}
	for (int i = 0 ; i < n ; i++) {
		for (int j = 0 ; j < m ; j++) {
			if (arr[i][j] == 0 && book[i][j] == 0) { // 寻找到可拓展却没被标记的作为起点
				cnt++ ;
				bfs(i, j) ;
			}
		} // 如果有多个样例记得将数组进行重置 
	} // 代码为: memset(arr, 0, sizeof(arr)) 在头文件<cstring>中,把数组重置为全为0
	cout << cnt << endl ;
	return 0 ;
}
相关推荐
程序员老舅9 分钟前
C++高并发精髓:无锁队列深度解析
linux·c++·内存管理·c/c++·原子操作·无锁队列
划破黑暗的第一缕曙光21 分钟前
[C++]:2.类和对象(上)
c++·类和对象
季明洵24 分钟前
C语言实现单链表
c语言·开发语言·数据结构·算法·链表
shandianchengzi28 分钟前
【小白向】错位排列|图文解释公考常见题目错位排列的递推式Dn=(n-1)(Dn-2+Dn-1)推导方式
笔记·算法·公考·递推·排列·考公
I_LPL29 分钟前
day26 代码随想录算法训练营 回溯专题5
算法·回溯·hot100·求职面试·n皇后·解数独
Yeats_Liao30 分钟前
评估体系构建:基于自动化指标与人工打分的双重验证
运维·人工智能·深度学习·算法·机器学习·自动化
墨雪不会编程31 分钟前
C++之【深入理解Vector】三部曲最终章
开发语言·c++
cpp_250133 分钟前
P9586 「MXOI Round 2」游戏
数据结构·c++·算法·题解·洛谷
浅念-38 分钟前
C语言编译与链接全流程:从源码到可执行程序的幕后之旅
c语言·开发语言·数据结构·经验分享·笔记·学习·算法
kyle~40 分钟前
ROS2---QoS策略
c++·机器人·ros2