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();
}
广度优先遍历: