这个是一个书上的例题,是个很典型的dfs的连通块的题目,这个遍历是调用自己这个函数完成的,与之前的bfs有点相像,但是这里的连通块主要还要注意一点,就是连通块的编号,算法的思路仍然是通过两个数组,一个录入信息,一个记录是否访问的数组。,然后这个是八连通,所以在遍历子节点中偷一点小懒,对于周边的遍历可以使从-1到1;然后一个if的判断,排除掉已经访问的,这个时候记录新的符合条件的值。
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int maxn=100+5; int m,n; int idx[maxn][maxn]; char pic[maxn][maxn]; void dfs(int r,int c,int id) { if(r>=m||r<0||c<0||c>=n) return ; if(idx[r][c]>0||pic[r][c]!='@') return ; idx[r][c]=id;//这里是连通分量;只有一个连通块循环完才会正式被算为1; for(int dr=-1;dr<=1;dr++)//这里就是之前提到的可以偷懒的地方,没有四连通这样要考虑怎么样安排这个次序 for(int dc=-1;dc<=1;dc++) if(dr!=0||dc!=0) dfs(r+dr,c+dc,id); } int main() { while(scanf("%d%d",&m,&n)==2&&m&&n) { for(int k=0;k<m;k++) scanf("%s",pic[k]); memset(idx,0,sizeof(idx)); int cnt=0; for(int i=0;i<m;i++) for(int j=0;j<n;j++ ) if(idx[i][j]==0&&pic[i][j]=='@') dfs(i,j,++cnt); printf("%d ",cnt);} return 0; }