链接:https://ac.nowcoder.com/acm/contest/558/J
来源:牛客网
小猫在研究网格图。
小猫在研究联通性。
给定一张N×M的网格图,只含字符0和1,问1形成的联通块有多少个。
两个1是联通的,当且仅当其中一个位于另一个的上、下、左、右四个方向之一。
输入描述:
第一行一个正整数T,表示数据组数。 每组数据的第一行两个正整数N,M,表示矩阵的长和宽。 接下来N行,每行M个字符0或1。
输出描述:
T行,每行一个正整数,表示每组数据的答案。
示例1
输入
2 3 5 10101 01110 10101 3 3 111 010 111
输出
5 1
备注:
1≤T,N,M≤50
思路:和油田一样bfs
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
char a[1009][1009];int n,m;
int book[1009][1009];
struct node{
int x,y,step;
node(){
}
node(int xx,int yy,int sstep):x(xx),y(yy),step(sstep){
}
};
queue<node>A;
const int rr[4][2] = {1,0,0,1,-1,0,0,-1};
void bfs(int x,int y,int step)
{
A.push(node(x,y,step));
book[x][y] = 1;
while(!A.empty())
{
node u =A.front();
A.pop();
for(int i = 0;i < 4;++i)
{
int xx = u.x+rr[i][0];
int yy = u.y+rr[i][1];
int ss = u.step=1;
if(xx<1 || xx >n || yy < 1 || yy > m || book[xx][yy] == 1 || a[xx][yy] == '0')
{
continue;
}
book[xx][yy] = 1;
A.push(node(xx,yy,ss));
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(book,0,sizeof(book));memset(a,0,sizeof(a));
string h;
scanf("%d%d",&n,&m);
for(int i = 1 ;i <= n;++i)
{
cin>>h;
for(int j = 1;j <= m;++j)
{
a[i][j] = h[j-1];
}
}int ans =0;
for(int i = 1 ;i <= n;++i)
{
for(int j = 1;j <= m;++j)
{
if(a[i][j] == '1' && book[i][j] == 0)
{
bfs(i,j,0);ans++;
}
}
}
printf("%d\n",ans);
}
return 0;
}