zoukankan      html  css  js  c++  java
  • ZOJ 3781 Paint the Grid Reloaded

    枚举,$BFS$,连通块缩点。

    可以枚举一开始染哪个位置,然后逐层往外染色,看最多需要多少操作次数,也就是算最短距离。连通块缩点之后可以保证是一个黑白相间的图,且每条边的费用均为$1$,$BFS$即可。

    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    using namespace std;
    
    int T,n,m;
    char s[50][50];
    int Belong[50][50],block,use[50*50];
    int dx[]={0,0,-1,1};
    int dy[]={1,-1,0,0};
    
    int h[50*50];
    struct Edge
    {
        int from,to,nx;
    }e[100000];
    int sz;
    
    bool ok(int x,int y)
    {
        if(x>=0&&x<n&&y>=0&&y<m) return 1;
        return 0;
    }
    
    void dfs(int x,int y)
    {
        Belong[x][y]=block;
        if(ok(x-1,y)&&s[x][y]==s[x-1][y]&&Belong[x-1][y]==0) dfs(x-1,y);
        if(ok(x+1,y)&&s[x][y]==s[x+1][y]&&Belong[x+1][y]==0) dfs(x+1,y);
        if(ok(x,y-1)&&s[x][y]==s[x][y-1]&&Belong[x][y-1]==0) dfs(x,y-1);
        if(ok(x,y+1)&&s[x][y]==s[x][y+1]&&Belong[x][y+1]==0) dfs(x,y+1);
    }
    
    void add(int x,int y)
    {
        e[sz].from=x; e[sz].to=y; e[sz].nx = h[x];
        h[x]=sz++;
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++) scanf("%s",s[i]);
    
            memset(Belong,block=0,sizeof Belong);
            sz=0;
            memset(h,0xff,sizeof(h));
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    if(Belong[i][j]) continue;
                    block++; dfs(i,j);
                }
            }
    
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    for(int k=0;k<4;k++)
                    {
                        int x=i+dx[k];
                        int y=j+dy[k];
                        if(!ok(x,y)) continue;
                        if(Belong[i][j]==Belong[x][y]) continue;
                        add(Belong[i][j],Belong[x][y]);
                    }
                }
            }
    
            int ans=0x7fffffff;
            for(int i=1;i<=block;i++)
            {
                memset(use,-1,sizeof(use));
                int mx=0;
                use[i]=0;
                queue<int>q;
                q.push(i);
                while(!q.empty())
                {
                    int x=q.front();
                    q.pop();
                    for(int j=h[x];j!=-1;j=e[j].nx)
                    {
                        int y=e[j].to;
                        if(use[y]!=-1) continue;
                        use[y]=use[x]+1;
                        mx=max(use[y],mx);
                        q.push(y);
                    }
                }
                ans=min(mx,ans);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    10. 正则表达式匹配
    5. 最长回文子串
    板子总结
    2020: 学生查询
    解决apt-get出错
    03如何计算算法的复杂度
    ad如何从PCB中导出元件封装库
    调车遇到的问题及解决办法
    java报错与解决方法总结
    SWD下载k60
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6561761.html
Copyright © 2011-2022 走看看