ZOJ3781. Paint the Grid Reloaded

Posted Angels_of_Death

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;

以上是关于ZOJ3781. Paint the Grid Reloaded的主要内容,如果未能解决你的问题,请参考以下文章

ZOJ - 3781 Paint the Grid Reloaded 题解

ZOJ - 3780-Paint the Grid Again-(拓扑排序)

ZOJ 3780 Paint the Grid Again(隐式图拓扑排序)

ZOJ 3780 E - Paint the Grid Again 拓扑排序

Paint the Grid Reloaded(缩点,DFS+BFS)

ZOJ 1610 Count the Colors(区间染色)