图的连通性涛哥有一张N*M的网格图,图上只含.和#,请问#形成的连通块有多少个。 两个#是联通的,当且仅当其中一个位于另外一个的上下左右四个方向之一。

输入:第一行两个正整数N、M,接下来N行,每行M个字符。
输出:输出一个正整数,表示答案。
输入样例1:3 5 输出样例1:5
#.#.#
.###.
#.#.#
提示:1≤N,M≤50

表示矩阵的长和宽。 接下来N行,每行M'图的连通性涛哥有一张N*M的网格图,图上只含.和#,请问#形成的连通块有多少个。 两个#是联通的,当且仅当其中一个位于另外一个的上下左右四个方向之一。


#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char g[55][55];
bool vis[55][55];
int n,m;

void dfs(int x,int y){  //深度优先搜索
    vis[x][y]=1;
    if(x>1&&!vis[x-1][y]&&g[x-1][y]=='#')dfs(x-1,y);
    if(y>1&&!vis[x][y-1]&&g[x][y-1]=='#')dfs(x,y-1);
    if(x<n&&!vis[x+1][y]&&g[x+1][y]=='#')dfs(x+1,y);
    if(y<m&&!vis[x][y+1]&&g[x][y+1]=='#')dfs(x,y+1);
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)scanf("%s",(g[i]+1));
    int ans=0;
    memset(vis,0,sizeof vis);
    for(int i=1;i<=n;++i)  //统计连通块个数
    for(int j=1;j<=m;++j)
    if(g[i][j]=='#'&&!vis[i][j]){dfs(i,j);++ans;}
    printf("%d\n",ans);
    return 0;
}

深度优先搜索。对于每一块#未遍历时,以它为起点开始搜索它所在的连通块,连通块个数加1;如果已经被遍历过,则跳过遍历继续枚举下一个。