zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    java传递String参数
    C++ string与int的互相转换
    java插入排序
    凸包Graham Scan算法实现
    求平面上N点最远两点和最近两点距离
    求最大公约数
    n个数连接得到最小或最大的多位整数(携程)
    Java快排
    背包问题
    二分查找离左边元素最近的(可以等于)
  • 原文地址:https://www.cnblogs.com/spciay/p/13383125.html
Copyright © 2011-2022 走看看