$\huge \color{orange}{成魔之路->}$ $\huge \color{purple}{算法提高课题解}$
思路:
1. cnt 表示连通块个数,area 表示连通块最大面积
2. 依次枚举每个点,如果该点没被记录过,就将其入队并记录该点
3. 取出队头,area ++
4. 枚举四个方向,左西,上北,右东,下南
5. 将符合的点入队,并记录该点
6. cnt 就是 bfs() 的次数,area 就是取各个连通块面积的最大值
完整代码
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N = 55;
int n,m;
int g[N][N];
bool st[N][N];
//左上右下
int dx[4]={0,-1,0,1},dy[4]={-1,0,1,0};
int bfs(int x,int y)
{
//将该点入队,并记录该点
queue<PII> q;
q.push({x,y});
st[x][y]=true;
int area=0;
while(q.size())
{
//取出队头,并让 area ++
auto t=q.front();
q.pop();
area++;
//枚举四个方向,西北东南
for(int i=0;i<4;i++)
{
int a=t.first+dx[i],b=t.second+dy[i];
//超出边界
if(a<0||a>=n||b<0||b>=m) continue;
//这个方向有堵墙
if(g[t.first][t.second]>>i&1) continue;
//该点已经被记录过了
if(st[a][b]) continue;
//将该点入队,并记录该点
q.push({a,b});
st[a][b]=true;
}
}
return area;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>g[i][j];
//cnt表示连通块个数,area表示连通块最大面积
int cnt=0,area=0;
//枚举每一个点
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(!st[i][j])
{
cnt++;
area=max(area,bfs(i,j));
}
cout<<cnt<<'\n'<<area<<endl;
return 0;
}