BFS与连通块结合

一、BFS

1.简介:广度优先,就是每次都尝试访问同一层的节点。 如果同一层都访问完,再访问下一层。

适用于找到边数最少的路径,当路径权值相同时,可以找最短合法路径.

2.伪代码
bfs(s) {
q = new queue()//先进先出采用队列
q.push(s), visited[s] = true//标记是否被访问过
while (!q.empty()) {//判空
auto t=q.front();//取出队头
u = q.pop()//出队列
for each edge(u, v) {//判断是否符合条件
new//根据t找到更多新的节点
if (!visited[v]&&...) {
q.push(v)//入队
visited[v] = true
}}}}
二、连通块
简而言之就是满足在题目条件下是连在一起的,有的题目是上下左右四个方向,有的则是包括斜对角的八个反向。
三.例题1:  
[蓝桥杯 2018 AB] 全球变暖 ( https://www.luogu.com.cn/problem/P8662 )
本题分为陆地和海水,因此在需要先遍历满足条件的,也就是为陆地且之前没有被访问过的可以进行BFS,进行多少次BFS就是有多少个连通块。
#include 
#define N 1010
using namespace std;
int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};//方向向量 
bool v[N][N];
int n,c=0,f=0;
char m[1010][1010];
typedef struct{
	int x,y;
}node;

queue q;

void bfs(int x,int y) 
{
	q.push({x,y});
	v[x][y]=true;
	while(!q.empty())
	{
		auto t=q.front();
		q.pop();
		if(t.x+1<=n&&t.y+1<=n&&t.x-1>=1&&t.y-1>=1)//范围 
		{
        if(m[t.x+1][t.y]=='#'&&m[t.x][t.y+1]=='#'&&m[t.x-1][t.y]=='#'&&m[t.x][t.y-1]=='#')
	   	    f=1;
	   	}
		for(int i=0;i<4;i++)
		{
			int tx=t.x+dx[i],ty=t.y+dy[i];
			if(tx<1||tx>n||ty<1||ty>n) continue;//范围 
			if(m[tx][ty]=='#'&&!v[tx][ty])
			{
				q.push({tx,ty});
				v[tx][ty]=true;
			}
		}
	}	
}

int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);//提高输入输出效率 
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>m[i][j];
		}
	}
	
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(m[i][j]=='#'&&!v[i][j])
			{
				f=0;
				bfs(i,j);
				if(f==0)
				{
					c++;
				}
			}
		}
	}
	cout<

你可能感兴趣的:(c++,宽度优先,开发语言,算法,数据结构,蓝桥杯)