连通块|c++基础--详细讲解

开头声明

本文由署髫亲自撰写并非转载

如果代码或文章内容有误,请大佬们及时指出。

部分内容是从网上复制的。

!!链接绝对安全无毒!!

点个呗~

基础理论

连通块其实就是求相邻格子的数量、有几块......通常用深度优先搜索来编写。

比如

10100
10110
01000
10110
00110

“ 1 ”代表不可通行,“ 0 ”代表可以通行,那么图中有几个连通块呢?(只能“上 左 下 右”来搜索)。可以看到图中有4个连通块(单个也算),最大的连通块是由5个块联通的。转化成数据就是:

1 0	1 0 0
1 0 1 1 0
0 1	0 0 0
1 0 1 1 0
0 0 1 1 0

连通块十分简单,所以我们直接上代码。

代码实践

1791 多少块水洼--[简单+]

描述

有一块 N×M 的土地,雨后积起了水,有水标记为‘W’,干燥为‘.’。八连通的积水被认为是连接在一起的。请求出院子里共有多少水洼?

输入描述

第一行为 N,M (1≤N,M≤100)。
下面为 N×M的土地示意图。

输出描述

一行,共有的水洼数。

#include<bits/stdc++.h>
using namespace std;
char mp[101][101];
int vis[101][101];
int n,m,cnt;
int dx[8]={0,1,1,1,0,-1,-1,-1},dy[8]={1,1,0,-1,-1,-1,0,1};
void dfs(int x,int y){
		for(int i=0;i<8;i++){
		int nx=x+dx[i],ny=y+dy[i];
		if(nx>0&&nx<=n&&ny>0&&ny<=m&&vis[nx][ny]==0&&mp[nx][ny]=='W'){
			vis[nx][ny]=1;
			dfs(nx,ny);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>mp[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(mp[i][j]=='W'&&vis[i][j]==0){
				vis[i][j]==1;
				dfs(i,j);
				cnt++;
			}
		}
	}
	cout<<cnt;
	return 0;
}

变量定义

char mp[101][101];
int vis[101][101];
int n,m,cnt;
int dx[8]={0,1,1,1,0,-1,-1,-1},dy[8]={1,1,0,-1,-1,-1,0,1};

mp是我们要输入的地图,vis是记录该位置有没有搜索过,n和m是地图(mp)的大小,dx和dy是搜索的4个方向,cnt来统计有几个连通块。

主函数

cin>>n>>m;
for(int i=1;i<=n;i++){
	for(int j=1;j<=m;j++){
		cin>>mp[i][j];
	}
}

先输入n和m,用来确定地图大小,再根据地图大小输入每一位。

for(int i=1;i<=n;i++){
	for(int j=1;j<=m;j++){
		if(mp[i][j]=='W'&&vis[i][j]==0){
			vis[i][j]==1;
			dfs(i,j);
			cnt++;
		}
	}
}

先用两个for循环遍历整个地图,看看有没有地图的i和j位是‘W’(水洼)且这个位置没有被搜索过。如果判断成功,那么就标记这一位搜索过了,且从该位开始搜索,搜索这一步是为了防止这块连通块 被再次搜索,最后连通块的数量(cnt)自增。

自定义函数

看过我写的深度优先搜索|c++基础--详细讲解的小伙伴应该熟悉自定义函数部分,连通块的自定义函数其实就是删改了深度优先搜索的的代码。

void dfs(int x,int y){
		for(int i=0;i<8;i++){
		int nx=x+dx[i],ny=y+dy[i];
		if(nx>0&&nx<=n&&ny>0&&ny<=m&&vis[nx][ny]==0&&mp[nx][ny]=='W'){
			vis[nx][ny]=1;
			dfs(nx,ny);
		}
	}
}

这段代码就不细说了,要注意的是这里的dfs函数是为了标记这个连通块里所有的块,而深度优先搜索的dfs函数是为了判断能不能走到目标位置

视角拓展

我给大家挑了几道简单的小题,大家可以做一做:

11228 猴群--[中等]

2542 贝茜在哪--[中等+]

6457 岛屿面积--[中等-]

都看到这儿了,就点个赞呗~

by~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值