T1:1097池塘计数
https://www.acwing.com/problem/content/1099/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#define N 2010
using namespace std;
typedef pair<int ,int> PII;
int n,m;
bool st[N][N];
char h[N][N];
queue<PII> q;
void bfs(int x,int y)
{
q.push({x,y});
st[x][y]=true;
while(!q.empty())
{
PII t=q.front();
q.pop();
for(int i=t.first-1;i<=t.first+1;i++)//九宫格遍历法
{
for(int j=t.second-1;j<=t.second+1;j++)
{
if(i==t.first && j==t.second)//本身的点跳过
continue;
if(i<=0 || i>n || j<=0 ||j>m)//超出范围的点跳过
continue;
if(st[i][j])//走过的点跳过
continue;
if(h[i][j]=='.')//是水的地方跳过
continue;
q.push({i,j});
st[i][j]=true;
}
}
}
}
int main()
{
int cnt=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>h[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(!st[i][j] && h[i][j]=='W')
{
bfs(i,j);
cnt++;
}
}
}
cout<<cnt<<endl;
return 0;
}
T2:1098. 城堡问题
https://www.acwing.com/problem/content/1100/
#include<bits/stdc++.h>
#include<queue>
#define N 55
#define M 55*55
using namespace std;
typedef pair<int,int> PII;
int n,m;
int g[N][N];
bool st[N][N];
queue<PII> q;
int bfs(int sx,int sy)
{
int dx[4]={0,-1,0,1};
int dy[4]={-1,0,1,0};
int ar=0;
q.push({sx,sy});
st[sx][sy]=true;
while(!q.empty())
{
PII t;
ar++;
t=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int a=t.first+dx[i];
int b=t.second+dy[i];
if(a<0 || a>=n || b<0 || b>=m)
continue;
if(st[a][b])
continue;
if(g[t.first][t.second] >> i & 1)//重点:墙的编号可以看做二进制位
continue;//左移i位&1则是判断i位上有没有1,按照dx,dy的顺序看这个方向有没有墙
q.push({a,b});
st[a][b]=true;
}
}
return ar;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>g[i][j];
int cnt=0,ar=0;//ar为面积
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(!st[i][j])
{
ar=max(ar,bfs(i,j));
cnt++;
}
cout<<cnt<<endl;
cout<<ar<<endl;
return 0;
}
T3:1106山峰和山谷
https://www.acwing.com/problem/content/1108/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define N 1010
using namespace std;
typedef pair<int ,int > PII;
int n;
int h[N][N];
queue<PII> q;
bool st[N][N];
void bfs(int sx,int sy,bool &flaghigh,bool &flaglow)
{
q.push({sx,sy});
st[sx][sy]==true;
while(!q.empty())
{
PII t;
t=q.front();
q.pop();
for(int i=t.first-1;i<=t.first+1;i++)
{
for(int j=t.second-1;j<=t.second+1;j++)
{
if(i<=0||i>n ||j<=0||j>n)
continue;
if(h[i][j]!=h[t.first][t.second])
{//只要不一样那就是山脉的边界
if(h[i][j]>h[t.first][t.second])//如果周围的小于该连通块则为山峰
flaghigh=true;
else//周围大于连通块则为山谷
flaglow=true;
}
else if(!st[i][j])//只有在等于的情况下才可以继续走
{
q.push({i,j});
st[i][j]=true;
}
}
}
}
}
int main()
{
int t;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>h[i][j];
int p,v;
p=0;v=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(!st[i][j])
{
bool flaghigh=false;
bool flaglow=false;
bfs(i,j,flaghigh,flaglow);
if(!flaghigh)
p++;
if(!flaglow)
v++;
}
}
}
cout<<p<<" "<<v<<endl;
return 0;
}
本文通过三个实例详细介绍了图遍历算法在不同问题中的应用:T1是池塘计数,使用BFS寻找由'W'字符构成的连通区域数量;T2是城堡问题,通过BFS计算没有被墙阻挡的最大区域;T3是山峰和山谷的识别,利用BFS确定地形中山峰和山谷的数量。这些例子展示了BFS在解决网格问题上的有效性。
242

被折叠的 条评论
为什么被折叠?



