ZOJ3781. Paint the Grid Reloaded

黑白染色模板题
首先通过DFS缩点,将所有相同状态的连通块缩成一个点
之后枚举每一个点进行BFS,计算变成最终状态的最小值

#include<bits/stdc++.h>
using namespace std;
const int N = 50, M = 2500;
int T, n, m, cnt, ans;
char s[N];
char g[N][N];
int h[M], e[4 * M], ne[4 * M], idx;
int st[N][N];
bool vis[M];
int dx[] = {1, 0, -1, 0};
int dy[] = {0, -1, 0, 1};
struct node {
    int dist, id;
};
int main() {
    scanf("%d", &T);
    while (T -- ) {
        scanf("%d%d", &n, &m);
        memset(st, 0, sizeof st);
        memset(h, -1, sizeof h);
        idx = 0;
        cnt = 1;
        for (int i = 1; i <= n; i ++ ) {
            scanf("%s", s + 1);
            for (int j = 1; j <= m; j ++ )
                g[i][j] = s[j];
        }
        function<void(int, int)> add = [&](int a, int b) {
            e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
        };
        //缩点
        function<void(int, int, int, char)> dfs = [&](int x, int y, int id, char ch) {
            for (int i = 0; i < 4; i ++ ) {
                int tx = x + dx[i];
                int ty = y + dy[i];
                if (tx < 1 || tx > n || ty > m || ty < 1)   continue;
                if (g[tx][ty] == ch) {
                    if (st[tx][ty] == 0) {
                        st[tx][ty] = id;
                        dfs(tx, ty, id, ch);
                    }
                }
                else if (st[tx][ty] != 0) {  //在缩点的同时完成加边操作
                    int temp = st[tx][ty];
                    add(id, temp), add(temp, id);
                }
            }
        };
        for (int i = 1; i <= n; i ++ ) {
            for (int j = 1; j <= m; j ++ ) {
                if (!st[i][j]) {
                    st[i][j] = cnt;
                    dfs(i, j, cnt, g[i][j]);
                    cnt ++;
                }
            }
        }
        ans = 0x3f3f3f3f;
        function<int(int)> bfs = [&](int x) {  //BFS计算每个起点变成最终状态的最小步数
            queue<node> q;
            q.push({0, x});
            int ans = -1;
            memset(vis, 0, sizeof vis);
            vis[x] = true;
            while (q.size()) {
                auto t = q.front();
                q.pop();
                ans = max(t.dist, ans);
                int u = t.id;
                for (int i = h[u]; i != -1; i = ne[i]) {
                    int j = e[i];
                    if (vis[j]) continue;
                    vis[j] = true;
                    q.push({t.dist + 1, j});
                }
            }
            return ans;
        };
        for (int i = 1; i < cnt; i ++ ) 
            ans = min(ans, bfs(i));
        printf("%d\n", ans);
    }
    return 0;
}
上一篇:GUI编程-Java


下一篇:理解ASP.NET Core - [03] Dependency Injection