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
";
            continue;
        }
        if (dfs(sx, sy)) cout << "YES
";  // 如果能够到达
        else cout << "NO
";  // 不能到达
    }
    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;
}
原文地址:https://www.cnblogs.com/spciay/p/13383125.html