关于 BFS
BFS,广搜,是一种寻找最短路、连通块的常用算法。我通常用队列实现
框架
连通块为例
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int dx[8] = {-1,-1,-1,0,0,1,1,1};// 方向,需要遍历的邻居
const int dy[8] = {-1,0,1,-1,1,-1,0,1};
int main() {
//
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,m;
cin>>n>>m;
vector<string>g(n);// 表
for(int i=0;i<n;i++)cin>>g[i];
int ans = 0;
queue<int>q;// 队列
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(g[i][j]!='W')continue;// 是否达到过,通常用vis[i][j]==1来判断
ans++;// 连通块
g[i][j] = '.';// 标记为达到过,通常用vis[i][j]=1
q.push(i*m+j);
while(!q.empty()){
int pos = q.front();
q.pop();// 出队
int x = pos / m;
int y = pos % m;
for(int d=0;d<8;d++){// 依次遍历每个方向
int nx=x+dx[d];// 邻居的x
int ny=y+dy[d];// 邻居的y
if(nx>=0 && nx < n && ny >= 0 && ny < m && g[nx][ny] == 'W'){// 判断该节点的每个需遍历邻居是否符合要求(存在且未达到)
g[nx][ny] = '.';// 标记为达到过,通常用vis[nx][ny]=1
q.push(nx*m+ny);// 入队
}
}
}
}
}
cout<<ans;
return 0;
}
大多数题目只需要在它的基础上加以改进即可
题目
{% del ps: 有兴趣的可以去洛谷找找,我懒得找了 %}
题目原文
题目描述
题意:有一块 N×M 的土地,雨后积起了水,有水标记为‘W’,干燥为‘.’。八连通的积水被认为是连接在一起的。请求出院子里共有多少水洼?
输入格式
第一行为 N,M(1≤N,M≤110)。
下面为 N*M 的土地示意图。
输出格式
一行,共有的水洼数。
样例
输入 1
10 12
W…WW.
.WWW…WWW
…WW…WW.
…WW.
…W…
…W…W…
.W.W…WW.
W.W.W…W.
.W.W…W.
…W…W.输出 1
3
数据范围与提示
无
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int dx[8] = {-1,-1,-1,0,0,1,1,1};
const int dy[8] = {-1,0,1,-1,1,-1,0,1};
int main() {
//
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,m;
cin>>n>>m;
vector<string>g(n);
for(int i=0;i<n;i++)cin>>g[i];
int ans = 0;
queue<int>q;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(g[i][j]!='W')continue;
ans++;
g[i][j] = '.';
q.push(i*m+j);
while(!q.empty()){
int pos = q.front();
q.pop();
int x = pos / m;
int y = pos % m;
for(int d=0;d<8;d++){
int nx=x+dx[d];
int ny=y+dy[d];
if(nx>=0 && nx < n && ny >= 0 && ny < m && g[nx][ny] == 'W'){
g[nx][ny] = '.';
q.push(nx*m+ny);
}
}
}
}
}
cout<<ans;
return 0;
}
ps: 最近有点累,加上生病了,博客更的比较少,见谅
原创
BFS广度优先搜索
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
赞赏支持
如果觉得文章对你有帮助,可以请作者喝杯咖啡 ☕
评论交流
欢迎留下你的想法