天天看点

dfs算法经典例题c语言,算法学习:深度优先搜索(DFS)经典例题(一)

题目描述

输入第一行输入一个整数N,表示共有N组测试数据

每一组数据都是先输入该地图的行数m(0

然后,输入接下来的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题,说白了就是暴力搜索的优化版本,属于不撞南墙不回头的算法,除非有东西阻挡,不然就会一直往下走,直到走完为止。

这题是求水池数目,我们可以用dfs对每个点的上下左右进行搜索,如果某个点的上下左右(某一个或多个)为1,则把这个点设置成0,一趟搜索来,我们可以把跟这个点连接的水池全部标记为0,然后给计数器变量加1,代表这整个为1个水池。只要对所有点都进行一遍dfs,则可以求出所有水池数目。

技巧:

①我们不用二维数组的第一行和第一列,并且将二维数组设置为num105,这样既可以防止数组越界,又可以用第1和101行已经第1列和101列来作为外围边界。

②初始时将二维数组全部设置为0,这样外围就存在边界了。

③将数组定义在外部,这样可以使dfs无序传数组的参数进入。

Coding:#include

#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<

}

return 0;

}