zoukankan      html  css  js  c++  java
  • 【数据结构】并查集

    并查集找格子图的连通分量

    int n, m;
        char g[1005][1005];
    
        int fa[1000005];
        int cnt[1000005];
        int id[1005][1005];
        int x[1000005];
        int y[1000005];
    
        int find(int x) {
            return fa[x] == x ? x : fa[x] = find(fa[x]);
        }
    
        void merge(int x, int y) {
            x = find(x), y = find(y);
            if(x == y)
                return;
            fa[x] = y;
            cnt[y] += cnt[x];
        }
    
        void init() {
            int N = n * m;
            for(int i = 1; i <= N; ++i) {
                fa[i] = i;
                cnt[i] = 1;
            }
            int top = 0;
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= m; ++j) {
                    ++top;
                    id[i][j] = top;
                    x[top] = i;
                    y[top] = j;
                }
            }
        }
    
        int dx[] = {0, 0, -1, 1};
        int dy[] = {-1, 1, 0, 0};
    
        char ans[1005][1005];
    
        void Read() {
            if(scanf("%d%d", &n, &m) == -1)
                exit(0);
            for(int i = 1; i <= n; ++i)
                scanf("%s", g[i] + 1);
        }
    
        void Solve() {
            init();
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= m; ++j) {
                    if(g[i][j] == '*')
                        continue;
                    for(int k = 0; k <= 3; ++k) {
                        int X = i + dx[k];
                        int Y = j + dy[k];
                        if(1 <= X && X <= n && 1 <= Y && Y <= m && g[X][Y] == '.') {
                            merge(id[X][Y], id[i][j]);
                        }
                    }
                }
            }
            memset(ans, 0, sizeof(ans));
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= m; ++j) {
                    if(g[i][j] == '*') {
                        vector<int> r;
                        int res = 1;
                        for(int k = 0; k <= 3; ++k) {
                            int X = i + dx[k];
                            int Y = j + dy[k];
                            if(1 <= X && X <= n && 1 <= Y && Y <= m && g[X][Y] == '.') {
                                int tr = find(id[X][Y]);
                                int suc = 1;
                                for(int &ri : r) {
                                    if(tr == ri) {
                                        suc = 0;
                                        break;
                                    }
                                }
                                if(suc) {
                                    r.push_back(tr);
                                    res += cnt[tr];
                                }
                            }
                        }
                        ans[i][j] = res % 10 + '0';
                    } else {
                        ans[i][j] = '.';
                    }
                }
            }
            for(int i = 1; i <= n; ++i)
                puts(ans[i] + 1);
        }
    
  • 相关阅读:
    Python前言之Markdown使用
    Linux压缩命令
    ubuntu安装nodejs
    linux搭建nginx流服务器,OBS推流,VCL拉流播放
    nginx配置文件
    控制语句
    鼠标用户和键盘用户
    if else
    cookie自封装对象
    C#:基于WMI查询USB设备信息 及 Android设备厂商VID列表
  • 原文地址:https://www.cnblogs.com/purinliang/p/14006908.html
Copyright © 2011-2022 走看看