DFS入门(连通块)

文章目录

一、连通块是什么?

什么是连通块?

可以理解为一个点的集合,若两点间可直接或间接的连接则两点在同一连通块中

举个例子:请大家数数,一共有多少个连通块(先来四个方向的 )

不出意外的话应该是6个,现在你已经过关连通块的概念了

二、基本代码形式

1.伪代码(4)

代码如下(示例): 

int dy[4]={0,1,-1,0};
int dx[4]={1,0,0,-1};
dfs(){
    搜索上下左右四个位置是否符合条件。
    if(符合条件) {
        标记
        dfs()
    }
}

按照任意顺序写都可以

2.伪代码(6)

int dx[6]={-1,-1,0,0,1,1};
int dy[6]={-1,0,-1,1,0,1};
dfs(){
    搜索六个位置是否符合条件。
    if(符合条件) {
        标记
        dfs()
    }
}

https://atcoder.jp/contests/abc269/tasks/abc269_d

#include <bits/stdc++.h>
#include <vector>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define ll long long
#define fir(v) (v).first
#define se(v) (v).second
#define pb(x) push_back(x)
#define pii pair<int,int>
#define all(a) (a).begin(),(a).end()
#define mp(a,b) make_pair(a,b)
#define For(i,n) for(int i=0;i<(n);i++)
#define fori(i,j,n) for(int i=j;i<(n);i++)
#define FOR(i,j,n) for(int i=j;i<=(n);i++)
using namespace std;
char a[2050][2050];
int cnt;
const int dx[]={-1,-1,0,0,1,1},dy[]={-1,0,-1,1,0,1};//六个方向 
void dfs(int x,int y){
	a[x][y]='.';//将初始点标记为 '.' 
	for(int i=0;i<6;i++){
		int nx=x+dx[i],ny=y+dy[i];
		if(a[nx][ny]=='#')//如果为'#' 那么继续往下搜索 
			dfs(nx,ny);
	}
}
int main(){
    memset(a,'.',sizeof(a));//初始化 
    int n;
    cin>>n;
    while(n--){
    	int x,y;
    	cin>>x>>y;
    	a[x+1000][y+1000]='#';  //防止越界 并且标记初始点 
	}
	for(int i=0;i<=2005;i++)
		for(int j=0;j<=2005;j++)
			if(a[i][j]=='#'){ 
				dfs(i,j); 
				cnt++; 
			}
	cout<<cnt<<endl;
	return 0;
}

3.伪代码(8)

int dx[6]={-1,0,1,1,1,0,-1,-1};
int dy[6]={-1,-1,-1,0,1,1,1,0};
dfs(){
    搜索八个位置是否符合条件。
    if(符合条件) {
        标记
        dfs()
    }
}


总结

总的来说,连通块中dfs充当的是标记地盘的作用,判断当前点,进行dfs(继续往下搜索)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值