Find connected blocks (BFS, DFS example)

topic:

Given an mxn matrix, the elements in the matrix are 0 or 1. It is said that the position (x, y) is adjacent to its four positions (x, y+1), (x, y-1) (x+1, y) (x-1, y). If there are several 1s in the matrix that are adjacent (not necessarily adjacent to each other), then these 1s are said to form a "block". Find the number of "blocks" in the given matrix.
Insert picture description here

Foreword: Record your thoughts so that you can come back and review it later

Ideas and points:

1. Set the array of direction increment:

int X[] = {
    
     0,0,1,-1 };		//方向增量数组
int Y[] = {
    
     1,-1,0,0 };

2. Set up a structure for recording point coordinates (pair is also available)

struct nod
{
    
    
	int x, y;
}node;

3. Record whether all points have been visited, visit a point and put him into the team, store him with temporary variables, pop him out of the team, for to broadly search for elements in his four directions, and then enter and leave the team separately. Use bool array to store whether a certain element has been enqueued, initially all FALSE

bool inq[6][7] = {
    
     false };				//判断元素是否入队

void bfs(int x, int y)	//BFS算法
{
    
    
	queue<nod>q;		//nod型队列
	node.x = x, node.y = y;	//实参传递
	q.push(node);
	inq[x][y] = true;
	while (!q.empty())
	{
    
    
		nod top = q.front();		//取出栈顶
		q.pop();					//栈顶出栈
		for (int i = 0; i < 4; i++)	//四个方向
		{
    
    
			int newx = top.x + X[i];
			int newy = top.y + Y[i];
			if (judge(newx, newy))		//如果说遍历的这个点需要访问
			{
    
    
				node.x = newx, node.y = newy;
				q.push(node);
				inq[newx][newy] = true;
			}
		}
	}
}

4. You don't have to enter BFS every time you visit. Write a judge function to determine whether he needs to visit. If the point has already entered the team or exceeds the boundary, skip it:

int main()
{
    
    
	int ans = 0;		//存放块数的答案
	for (int i = 0; i < 6; i++)
		for (int j = 0; j < 7; j++)
		{
    
    
			if (a[i][j] == 1 && inq[i][j] == false)//如果没被入队过并且点权等于1,那么就BFS,否则就下一个a[i][j]
			{
    
    
				ans++;
				bfs(i, j);
			}
		}
}

Or access judgment in BFS:

bool judge(int x, int y)
{
    
    
	if (x >= 6 || x < 0 || y >= 7 || y < 0) return false;
	if (inq[x][y] == true || a[x][y] == 0) return false;
	//都不符合情况, 返回真
	return true;
}

BFS complete implementation code:

#include<algorithm>
#include<stdio.h>
#include<string.h>
#include <iostream>
#include<string>
#include<queue>
using namespace std;

struct nod
{
    
    
	int x, y;
}node;

int X[] = {
    
     0,0,1,-1 };		//方向增量数组
int Y[] = {
    
     1,-1,0,0 };

int a[6][7] = {
    
    			//01地图矩阵
			{
    
    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}
};

bool inq[6][7] = {
    
     false };				//判断元素是否入队

bool judge(int x, int y)
{
    
    
	if (x >= 6 || x < 0 || y >= 7 || y < 0) return false;
	if (inq[x][y] == true || a[x][y] == 0) return false;
	//都不符合情况, 返回真
	return true;
}

void bfs(int x, int y)
{
    
    
	queue<nod>q;		//nod型队列
	node.x = x, node.y = y;	//实参传递
	q.push(node);
	inq[x][y] = true;
	while (!q.empty())
	{
    
    
		nod top = q.front();		//取出栈顶
		q.pop();					//栈顶出栈
		for (int i = 0; i < 4; i++)	//四个方向
		{
    
    
			int newx = top.x + X[i];
			int newy = top.y + Y[i];
			if (judge(newx, newy))		//如果说遍历的这个点需要访问
			{
    
    
				node.x = newx, node.y = newy;
				q.push(node);
				inq[newx][newy] = true;
			}
		}
	}
}

int main()
{
    
    
	int ans = 0;		//存放块数
	for (int i = 0; i < 6; i++)
		for (int j = 0; j < 7; j++)
		{
    
    
			if (a[i][j] == 1 && inq[i][j] == false)
			{
    
    
				ans++;
				bfs(i, j);
			}
		}
	for (int i = 0; i < 6; i++) {
    
    
		for (int j = 0; j < 7; j++)
			cout << a[i][j] << " ";
		cout << endl<<endl;
	}
	cout << "一共"<<ans<<"个联通分块!";
	return 0;
}

DFS function implementation: (stack used by dfs)

void dfs(int x, int y)
{
    
    
	stack<nod>w;		//队列	
	node.x = x, node.y = y;
	w.push(node);		//进栈
	inq[x][y] = true;	//记录进栈
	for (int i = 0; i < 4; i++)
	{
    
    
		if (judge(x + X[i], y + Y[i]))//符合条件就DFS
		{
    
    
			dfs(x + X[i], y + Y[i]);
		}
	}
	w.pop();		//如果四个方向访问后退回,代表没有路走了,出栈
}

test:

Afterword: 35Days

Guess you like

Origin blog.csdn.net/Kyrie_irving_kun/article/details/114790371