深度搜索又叫深度优先遍历(DFS,Depth-firstSearch),是搜索常用的手段之一。它从一个状态出发,不断地转移状态,直到无法转移,就回退到前一步的状态,继续转移到其他状态,这样不断地重复下去,直到找到最终的解为止。下面就以poj和woj上的两个经典题目为例进行简单地说明。
poj2386 Lake Counting
题目链接:
http://poj.org/problem?id=2386
题目的大概意思就是有一个N*M的园子,雨后积水。八连通的积水被认为是连接在一起的。指定输出,给出水洼的数目。数据规模:1 <= N <= 100; 1 <= M <= 100,时间限制是1s,内存限制是65536KB。
这就是一道很经典的深度搜索问题,一些公司的笔试也经常出这种题目。可以这样考虑,从任意的w地方开始出发,每次遇到四周的邻接w就替换成“·”。一次进行DFS后,与初始的这个w开始邻接的所有的w就被替换成了“·”,直到图中不再存在w为止,总共进行的DFS的次数就是要输出的答案。时间复杂度为O(8*N*M)=O(N*M)。
AC代码如下:
#include<iostream> #include<stdio.h> using namespace std; const int MAX_N=101; const int MAX_M=101; int n,m; char field[MAX_N][MAX_M]; void dfs(int x,int y) { field[x][y]='.'; for(int dx=-1;dx<=1;++dx) { for(int dy=-1;dy<=1;++dy) { int nextX=x+dx,nextY=y+dy; if(nextX>=0&&nextX<n&&nextY>=0&&nextY<m&&field[nextX][nextY]=='W') dfs(nextX,nextY); } } return ; } int main() { freopen("in.txt","r",stdin); while(cin>>n>>m) { for(int i=0;i<n;++i) { for(int j=0;j<m;++j) { cin>>field[i][j]; } } int ans=0; for(int i=0;i<n;++i) { for(int j=0;j<m;++j) { if(field[i][j]=='W') { dfs(i,j); ans++; } } } cout<<ans<<endl; } return 0; }
woj1167 Oil Detecting
题目链接:
http://acm.whu.edu.cn/learn/problem/detail?problem_id=1167
跟上一题几乎一样,解法也一样。AC代码如下:
/* Name:Li Jiansong Copyright: Author: Date: 04/01/16 03:34 Description: woj1167 深度搜索 */ #include<iostream> #include<stdio.h> using namespace std; #pragma warning(disable:4996) int r, c; int dx[] = { 0, 1, -1, 1, -1, 0, 1, -1 }; int dy[] = { 1, 1, 1, 0, 0, -1, -1, -1 }; int nextX, nextY; char matrix[100][100]; void Dfs(int x, int y) { if (x<c&&x >= 0 && y<r&&y >= 0) { if (matrix[y][x] == 'O') { matrix[y][x] = 'X'; for (int i = 0; i<8; i++) { nextX = x + dx[i]; nextY = y + dy[i]; Dfs(nextX, nextY); } } else return; } else return; } int main() { freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); int count; while (cin >> r >> c&&r != 0 && c != 0) { count = 0; for (int i = 0; i<r; ++i) { for (int j = 0; j<c; ++j) { cin >> matrix[i][j]; } } for (int i = 0; i<r; ++i) { for (int j = 0; j<c; ++j) { if (matrix[i][j] == 'O') { count++; Dfs(j,i); } } } cout << count << endl; } return 0; }