【深搜】Lake Counting

Lake Counting(POJ No.2386)

有一个大小为 N * M 的园子,雨后积了水。八连通的积水被认为是连接在一起的。请求出园子里总共有多少水洼?

N = 10,M = 12

园子如下图(‘ W ’表示积水,‘ . ’表示没有积水)

W........WW.

.WWW.....WWW

....WW...WW.

.........WW.

.........W..

..W......W..

.W.W.....WW.

W.W.W.....W.

.W.W......W.

..W.......W.

深度优先遍历

思路:从任意的 W 开始,不停把邻接的部分‘ . 代替。1次 DFS 后与初始这个 W 连接的所有 W 就都被替换成了‘ . ’,因此直到图中不在存在 W 为止,总共进行的 DFS 次数就是答案。8个方向共对应了8种状态转移,每个格子作为 DFS 的参数至多被调用一次,所以复杂度为O(8 * N * M)=O(N * M)。

#include<iostream>
using namespace std;

int M = 4;
int N = 4;
char field[4][4]={'W','.','W','.',
		  'W','.','.','.',
		  'W','W','.','W',
		  'W','.','.','W'};

//现在位置(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 ++){
			int nx = x + dx;
			int ny = y + dy;
			//判断(nx,ny)是不是在园子里,以及是否有积水
			if(0 <= nx && nx < N && 0 <= ny && ny <M && field[nx][ny] == 'W')
				dfs(nx,ny); 
		}
	} 
	return ;
}

void solve(){
	int res = 0;
	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;
}

int main(){
	solve();	 
}

广度优先遍历:

猜你喜欢

转载自blog.csdn.net/cjw838982809/article/details/108137001