Primera búsqueda en profundidad (DFS)
La búsqueda en profundidad es uno de los medios de búsqueda. Comienza desde un cierto estado y continúa transfiriendo el estado hasta que no se puede transferir, luego regresa al estado del paso anterior, continúa transfiriéndose a otros estados y repite de esta manera hasta que se encuentra la solución final.
La búsqueda en profundidad (implícita) utiliza la pila para el cálculo. La pila admite operaciones push y pop, y los elementos de datos son los últimos en entrar, primero en salir.
Ejemplo: Conteo de lagos (POJ No 2386)
Descripción del Título
Hay un jardín de tamaño N * M y el agua se ha acumulado después de la lluvia. Se considera que ocho aguas estancadas conectadas están conectadas entre sí. Pregunte cuántos charcos hay en el jardín. (Ocho conectividad se refiere a la parte * relativa a W en la figura siguiente)
***
*W*
***
Restricciones:
N, M <= 100
Entrada de muestra
N = 10, M = 12 El
jardín es como se muestra a continuación ('W' significa agua estancada, '.' Significa que no hay agua estancada)
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.
Salida de muestra
3
Análisis de temas
Desde un W
comienzo arbitrario , siga ‘.’
reemplazando la parte adyacente con . Después de un DFS, W
todos los W conectados al inicial se reemplazan ‘.’
, por lo que hasta que no haya más W en la figura, el número total de DFS es la respuesta. Las 8 direcciones corresponden a un total de 8 transiciones de estado. Cada cuadrícula se llama como máximo una vez como parámetro de DFS, por lo que la complejidad es O (8 × N × M) = O (N × M)
Código
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_N = 10001;
int N,M;
char field[MAX_N][MAX_N+1]; //园子
//现在位置( x, y )
void dfs(int x, int y){
//将现在所在位置替换为 .
field[x][y] = '.';
//循环遍历移动的8个方向
for(int dx = -1; dx<=1; dx++){
for(int dy = -1; dy<=1; dy++){
// 向x方向移动dx,向y方向移动dy,移动的结果为(nx, ny)
int nx = x + dx, ny = y + dy;
// 判断(nx, ny)是不是在园子内,以及是否有积水
if(0<=nx && nx < N && 0<=ny && ny < M && field[nx][ny] =='W')
dfs(nx,ny);
}
}
return ;
}
int main(){
cin >> N >> M;
int res = 0;
for(int i=0; i<N; i++){
for(int j=0; j<M; j++)
cin >> field[i][j];
}
for(int i=0; i<N; i++){
for(int j=0; j<M; j++)
if(field[i][j] == 'W'){
//从有W的地方开始dfs
dfs(i,j);
res++;
}
}
cout << res << endl;
return 0;
}