dfs连通性模型
dfs连通性模型
1. 算法分析
使用dfs来判断是否两个点连通,也可以通过dfs来做计数
2. 例题
acwing1112迷宫
T个测试样例,每个测试样例输入一个N,表示网格大小。网格为N*N的二维网格,给定起点和终点,问起点能否到达终点
#include <bits/stdc++.h>
using namespace std;
int const N = 1e2 + 10;
int T, n, sx, sy, ex, ey, st[N][N];
char a[N][N];
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0 , -1};
// dfs判断能否到达
bool dfs(int x, int y) {
for (int i = 0; i < 4; ++i) { // 4个方向
int next_x = x + dx[i], next_y = y + dy[i];
if (next_x < 0 || next_x > n - 1 || next_y < 0 || next_y > n - 1 || a[next_x][next_y] == '#') continue; // 不能走
if (next_x == ex && next_y == ey) return true; // 到达
if (st[next_x][next_y]) continue;
st[next_x][next_y] = 1; // 记录
if (dfs(next_x, next_y)) return true; // 判断next_x,next_y开始能否到达
}
return false;
}
int main() {
cin >> T;
while (T--) {
memset(st, 0, sizeof st);
cin >> n;
for (int i = 0; i < n; ++i) scanf("%s", a[i]); // 输入网格
cin >> sx >> sy >> ex >> ey;
if (a[sx][sy] == '#' || a[ex][ey] == '#') { // 特判
cout << "NO\n";
continue;
}
if (dfs(sx, sy)) cout << "YES\n"; // 如果能够到达
else cout << "NO\n"; // 不能到达
}
return 0;
}
acwing1113红与黑
有一间长方形(N*M)的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖('@')上,只能向相邻(上下左右四个方向)的黑色瓷砖('.')移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。
1)‘.’:黑色的瓷砖;
2)‘#’:白色的瓷砖;
3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。
N、M~20
#include <bits/stdc++.h>
using namespace std;
int const N = 40;
int T, n, m, sx, sy, st[N][N], res;
char a[N][N];
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0 , -1};
void dfs(int x, int y) { // dfs计数
for (int i = 0; i < 4; ++i) {
int next_x = x + dx[i], next_y = y + dy[i];
if (next_x < 0 || next_x > n - 1 || next_y < 0 || next_y > m - 1 || st[next_x][next_y] || a[next_x][next_y] == '#') continue;
st[next_x][next_y] = 1;
res++;
dfs(next_x, next_y);
}
return;
}
int main() {
while (cin >> m >> n && n && m) {
memset(st, 0, sizeof st);
for (int i = 0; i < n; ++i) { // 读入矩阵
scanf("%s", a[i]);
for (int j = 0; j < m; ++j) {
if (a[i][j] == '@') {
sx = i, sy = j;
}
}
}
st[sx][sy] = 1; // 记录初始位置
res = 1;
dfs(sx, sy); // 从初始位置开始dfs
cout << res << endl;
}
return 0;
}
更多精彩