nyoj27-水池数目 (求连通块数目)【dfs】

http://acm.nyist.net/JudgeOnline/problem.php?pid=27

水池数目

时间限制: 3000 ms  |  内存限制:65535 KB
难度: 4
 
描述
南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池,假设有一张我们学校的某处的地图,这个地图上仅标识了此处是否是水池,现在,你的任务来了,请用计算机算出该地图中共有几个水池。
 
输入
第一行输入一个整数N,表示共有N组测试数据
每一组数据都是先输入该地图的行数m(0<m<100)与列数n(0<n<100),然后,输入接下来的m行每行输入n个数,表示此处有水还是没水(1表示此处是水池,0表示此处是地面)
输出
输出该地图中水池的个数。
要注意,每个水池的旁边(上下左右四个位置)如果还是水池的话的话,它们可以看做是同一个水池。
样例输入
2

3 4

1 0 0 0 

0 0 1 1

1 1 1 0

5 5

1 1 1 1 0

0 0 1 0 1

0 0 0 0 0

1 1 1 0 0

0 0 1 1 1
样例输出
2

3

 

题意:就是求这个二维地图上由1组成的连通块的数目。

题解1:dfs

 1 #include <fstream>

 2 #include <iostream>

 3 #include <cstdio>

 4 #include <cstring>

 5 

 6 using namespace std;

 7 

 8 const int N=100;

 9 int m,n,ans;

10 int a[N][N];

11 bool b[N][N];

12 int xy[2][4]={{1,-1,0,0},{0,0,1,-1}};

13 

14 bool check(int x,int y);

15 void dfs(int x,int y);

16 

17 int main()

18 {

19     //freopen("D:\\input.in","r",stdin);

20     //freopen("D:\\output.out","w",stdout);

21     int T;

22     scanf("%d",&T);

23     while(T--){

24         ans=0;

25         scanf("%d%d",&m,&n);

26         for(int i=0;i<m;i++)

27             for(int j=0;j<n;j++)

28                 scanf("%d",&a[i][j]);

29         memset(b,0,sizeof(b));

30         for(int i=0;i<m;i++)

31             for(int j=0;j<n;j++)

32                 if((!b[i][j])&&a[i][j])    dfs(i,j),ans++;

33         printf("%d\n",ans);

34     }

35     return 0;

36 }

37 bool check(int x,int y){

38     return x>=0&&x<m&&y>=0&&y<n&&b[x][y]==0;

39 }

40 void dfs(int x,int y){

41     b[x][y]=1;

42     if(!a[x][y])    return;

43     int tx,ty;

44     for(int i=0;i<4;i++){

45         tx=x+xy[0][i];

46         ty=y+xy[1][i];

47         if(check(tx,ty))  dfs(tx,ty);

48     }

49 }

题解2:非递归方式:队列。建立队列q,遍历二维图所有点,对每个点扩展的点存入队列,再一一处理。

 1 #include <stdio.h>

 2 

 3 int main()

 4 {

 5     int t,n,m,e=1000,i,j,k,s,num,q[10010],r[110][110];

 6     scanf("%d",&t);

 7     while(t--)

 8     {

 9         scanf("%d%d",&n,&m);

10         for(i=0;i<n;i++)

11             for(j=0;j<m;j++)

12                 scanf("%d",&r[i][j]);

13         num=0;

14         for(i=0;i<n;i++)

15             for(j=0;j<m;j++)

16             {

17                 if(r[i][j]==1)

18                 {

19                     int a,b;

20                     a=i;

21                     b=j;

22                     k=1;

23                     s=0;

24                     while(s<k)

25                     {

26                         if(r[a][b-1]==1)

27                         {

28                             q[k++]=a*e+b-1;

29                             r[a][b-1]=0;

30                         }

31                         if(r[a][b+1]==1)

32                         {

33                             q[k++]=a*e+b+1;

34                             r[a][b+1]=0;

35                         }

36                         if(r[a-1][b]==1)

37                         {

38                             q[k++]=(a-1)*e+b;

39                             r[a-1][b]=0;

40                         }

41                         if(r[a+1][b]==1)

42                         {

43                             q[k++]=(a+1)*e+b;

44                             r[a+1][b]=0;

45                         }

46                         a=q[++s]/e;

47                         b=q[s]%e;

48                     }

49                     num++;

50                 }

51             }

52         printf("%d\n",num);

53     }

54     return 0;

55 }

你可能感兴趣的:(DFS)