油田

这个是一个书上的例题,是个很典型的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\n",cnt);}
    return 0;
}

  

posted @ 2016-07-16 16:08  阿银家的小贰  阅读(98)  评论(0编辑  收藏  举报