天天看點

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;

}