//求输入的矩阵中8连通的W的块数,求连通区域数,首先就想到的是广度优先搜索。用一个FIFO的队列来保存同一个连通区域的W。
#include <iostream>
#include <queue>
using namespace std;
enum color{white,gray,black}; //标记颜色,
char feild[102][102];
color squarecolor[102][102];
int x[8]={-1,0,1,-1,1,-1,0,1}; //x,y当前点的领域坐标
int y[8]={-1,-1,-1,0,0,1,1,1};
//算法复杂度O(N*M*W的个数)
int main()
{
queue<int> coor;
int N,M,result=0;
cin>>N>>M;
for (int i=1;i<=N;++i)
{
for(int j=1;j<=M;++j)
{
cin>>feild[i][j];
squarecolor[i][j]=white; //初始所有点颜色为white
}
}
//边界条件
for (int i=0;i<=N+1;++i)
{
feild[i][0]='.';
feild[i][M+1]='.';
}
for (int j=0;j<=M+1;++j)
{
feild[0][j]='.';
feild[N+1][j]='.';
}
int row,col;
for (int i=1;i<=N;++i)
{
for(int j=1;j<=M;++j)
{
if (feild[i][j]=='W') //若为W,且为white,代表该点还没探索过,说明是新的联通区域,可作为搜索起始点。
{
if(squarecolor[i][j]==white)
{
coor.push(i*(M+1)+j); //将该点的坐标保存进队列
squarecolor[i][j]=gray; //该点进入队列后,变为gray
++result; //连通区域个数加1
//cout<<i<<" "<<j<<endl;
}
}
while(!coor.empty()) //用广度优先探索连通区域的过程
{
row=coor.front()/(M+1);
col=coor.front()%(M+1);
coor.pop();
for (int k=0;k<8;++k)
{
int temprow=row+y[k];
int tempcol=col+x[k];
if (feild[temprow][tempcol]=='W')
{
if (squarecolor[temprow][tempcol]==white)//如果领域中有白色的W,就使其入队,并赋为gray
{
coor.push(temprow*(M+1)+tempcol);
squarecolor[temprow][tempcol]=gray;
}
}
}
squarecolor[row][col]=black;
}
}
}
cout<<result;
return 0;
}
poj 2386 Lake Counting 解题报告(BFS)
最新推荐文章于 2020-01-15 15:57:29 发布