当前位置: 代码迷 >> 综合 >> Flood Fill算法(dfs bfs)
  详细解决方案

Flood Fill算法(dfs bfs)

热度:74   发布时间:2023-12-13 23:32:10.0

问题本质:联通体面积

深搜简略版描述: 没有出口, 能走就走, 累加递归的结果。

广搜简略版描述:不断拓展新边界,累加后入队。

例题参考:迷雾森林、红与黑   这里举迷雾森林的例子(90%参考y总)

描述

迷雾森林被加农的玷污了,原本圣洁无比的迷雾森林,如今被彻底玷污,空气中充满着紫色的恶臭。

林克临危不惧,带上呼吸面罩,挥舞大师之剑的光芒,净化迷雾。林克所到之处,加农褪去,圣洁回归。

如下图,红色代表墙壁,紫色的迷雾代表需要净化的空间,金色代表林克开始净化的起点。

从某处开始,林克只能向相邻的紫色区域移动。请问,林克总共能够净化多少区域?

图1 初始状态                                                                图2   净化中.....

-----

输入

包括多个数据集合。每个数据集合的第一行是两个整数W和H,分别表示x方向和y方向瓷砖的数量。W和H都不超过20。

在接下来的H行中,每行包括W个字符。

每个字符表示一个区域的状态,规则如下

1)‘.’:代表紫色迷雾

2)‘#’:代表红墙

3)‘@’:代表林克的起始位置

(该字符在每个数据集合中唯一出现一次。)

当在一行中读入的是两个零时,表示输入结束。

输出

对每个数据集合,分别输出一行,显示林克从初始位置出发能净化的迷雾数(记数时包括初始位置的迷雾)。

输入样例 1 

6 9 ....#. .....# ...... ...... ...... ...... ...... #@...# .#..#. 0 0

输出样例 1

45

深搜写法:优点:简单代码少    缺点:数据大有爆栈的风险 

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;typedef long long LL;const int N = 35;
bool st[N][N];
char g[N][N];
int w, h;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};int dfs(int x, int y){int cnt = 1;st[x][y] = true;for(int i = 0; i < 4; ++ i){int nx = x + dx[i], ny = y + dy[i];//	cout << nx << ny << endl;                 if(nx < 0 || nx >= h || ny < 0 || ny >= w) continue;   //出界if(st[nx][ny]) continue;                               //走过 if(g[nx][ny] == '#') continue;                         //墙壁cnt += dfs(nx, ny);    //累加//	cout << cnt << endl;}return cnt;
}int main(){while(cin >> w >> h, w || h){for(int i = 0; i < h; ++ i) cin >> g[i];int x, y;for(int i = 0; i < h; ++ i)for(int j = 0; j < w; ++ j){if(g[i][j] == '@'){x = i; y = j;                      //标记出发点}}cout << dfs(x, y) << endl;memset(st, 0, sizeof st);}return 0;
}

 广搜写法: 1.优点:没有爆栈的风险,运行更优     2.缺点:要建个队列,写起来麻烦一点


//联通体
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;#define x first
#define y secondtypedef pair<int, int> PII;   //因为要入队 所以一起存比较方便const int N = 25;
char g[N][N];
int w, h, res = 1;
bool st[N][N];int bfs(PII start){queue<PII> q;q.push(start);st[start.x][start.y] = true;int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};while(q.size()){                                              //Flood fill算法  不断拓展新边界PII tmp = q.front();q.pop();for(int i = 0; i < 4; ++ i){int x = tmp.x + dx[i], y = tmp.y + dy[i];if(x >= h || x < 0 || y >= w || y < 0) continue;if(g[x][y] == '#') continue;if(st[x][y]) continue;++ res;st[x][y] = true;q.push({x, y});}}return res;
}int main(){while(cin >> w >> h && w || h){           //非0输入res = 1; memset(st, false, sizeof st);for(int i = 0; i < h; ++ i) cin >> g[i];PII start;for(int i = 0; i < h; ++ i){for(int j = 0; j < w; ++ j){if(g[i][j] == '@')  start = {i, j};}}cout << bfs(start) << endl;
}return 0;
}

  相关解决方案