算法学习:深度优先搜索(DFS)

题目描述

南阳理工学院校园里有一些小河和一些湖泊,如今,咱们把它们通一当作水池,假设有一张咱们学校的某处的地图,这个地图上仅标识了此处是不是水池,如今,你的任务来了,请用计算机算出该地图中共有几个水池。

输入

第一行输入一个整数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

这题是一道简单的dfs题目,dfs题,说白了就是暴力搜索的优化版本,属于不撞南墙不回头的算法,除非有东西阻挡,否则就会一直往下走,直到走完为止。c++

这题是求水池数目,咱们能够用dfs对每一个点的上下左右进行搜索,若是某个点的上下左右(某一个或多个)为1,则把这个点设置成0,一趟搜索来,咱们能够把跟这个点链接的水池所有标记为0,而后给计数器变量加1,表明这整个为1个水池。只要对全部点都进行一遍dfs,则能够求出全部水池数目。算法

技巧:
①咱们不用二维数组的第一行和第一列,而且将二维数组设置为num105,这样既能够防止数组越界,又能够用第1和101行已经第1列和101列来做为外围边界。
②初始时将二维数组所有设置为0,这样外围就存在边界了。
③将数组定义在外部,这样可使dfs无序传数组的参数进入。
Coding:数组

#include <bits/stdc++.h>
#define N 105
using namespace std;
int arr[N][N];

void dfs(int a,int b)
{
    if(arr[a-1][b]==1){arr[a-1][b]=0,dfs(a-1,b);}  //向上搜索
    if(arr[a+1][b]==1){arr[a+1][b]=0,dfs(a+1,b);}  //向下搜索
    if(arr[a][b-1]==1){arr[a][b-1]=0,dfs(a,b-1);}  //向左搜索
    if(arr[a][b+1]==1){arr[a][b+1]=0,dfs(a,b+1);}  //向右搜索
}
int main(void)
{
    int t;
    int n,m;
    cin>>t;
    while(t--)
    {
        int cnt=0;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>arr[i][j];

        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if(arr[i][j]==1)   //表明此点为水池
                {
                    cnt++;
                    dfs(i,j);     //将与该水池相邻的水池都标记为0
                }
            }

            cout<<cnt<<endl;
    }

    return 0;
}
相关文章
相关标签/搜索