• [C++]油田(Oil Deposits)-用DFS求连通块


    [本博文非博主原创,均摘自:刘汝佳《算法竞赛入门经典》(第2版) 6.4 图]

    [程序代码根据书中思路,非独立实现]

    例题6-12 油田(Oil Deposits,UVa572)

      输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块。如果两个字符“@”所在的格子相邻(横、纵或者对角线方向),就说它们属于一个八连块。例如,下图中有两个八连块。

    一、分析

      1.1 整体思路

      图也有DFS和BFS遍历。由于DFS更容易编写,一般用DFS查找连通块:从每个"@"格子出发,递归遍历它周围的"@"格子。每次访问一个格子时,就给它写上一个"连通分量编号",这样就可以在访问之前检查它是否已经有了编号,从而避免同一个格子访问多次。

      1.2 各坐标的邻接位置(3X3)扫描器

    二、程序实现

    //用DFS求连通块
    #include<iostream>
    #include<string.h>
    using namespace std;
    
    const int maxn = 105;
    int cnt;
    int *cntArray;
    char matrix[maxn][maxn];
    int idx[maxn][maxn];//标记数组
    int m;
    int n;
    
    void print(int rows, int cols){
        for(int i=0;i<rows;i++){
            for(int j=0;j<cols;j++){
                printf("%d	", idx[i][j]);
            }
            printf("
    ");
        }
    }
    
    void dfs(int row,int col,int id){
        if(row<0 || row>=m || col <0 || col >=n)
            return;//边界
        if((matrix[row][col] != '@') || (idx[row][col] > 0))//已被标记或者不是@区域
            return;
        idx[row][col] = id;
        for(int drow=-1;drow<2;drow++){//(邻接)扫描器
            for(int dcol=-1;dcol<2;dcol++){
                dfs(row + drow, col + dcol, id);
            }
        }
    }
    
    int countIdx(){
        cntArray = new int[cnt+1];
        memset(cntArray, 0, sizeof(cntArray));
        int cursor = 0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                cursor = matrix[i][j];
                cntArray[cursor]++;
            }
        }
    }
    
    int main(){
        while(scanf("%d %d", &m, &n) == 2 && m && n){
            for(int i=0;i<m;i++){
                scanf("%s", matrix[i]);
            }
            memset(idx, 0, sizeof(idx));
            int cnt = 0;
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(idx[i][j] == 0 && matrix[i][j] == '@')
                    dfs(i, j, ++cnt);
                }
            }
            print(m, n);
        }
        return 0;
    }
    /*
    5 5
    ****@
    *@@*@
    *@**@
    @@@*@
    @@**@
    */

    效果图:

    三、参考文献

      1.刘汝佳.算法竞赛入门经典

  • 相关阅读:
    Vue 02
    Vue 初识
    复杂数据类型之函数 对象
    Collections工具类
    遍历集合的方法总结
    使用Iterator迭代器遍历容器元素(List/Set/Map)
    TreeSet的使用和底层实现
    HashSet基本使用
    HashSet底层实现
    TreeMap的使用和底层实现
  • 原文地址:https://www.cnblogs.com/johnnyzen/p/9095260.html
Copyright © 2020-2023  润新知