首页 > 代码库 > zoj3781 Paint the Grid Reloaded --- 缩点 bfs

zoj3781 Paint the Grid Reloaded --- 缩点 bfs

╮(╯▽╰)╭水题

相连的相同色块缩成点,和相邻的不同色块建边。

以每一个点为起点bfs,求最小答案。


#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#define ll long long
#define mod 1000000007
using namespace std;

char mp[45][45];
int num[1610],cnt,n,m,vis[1610];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
vector<int> v[1600];

struct node
{
    int d,id;
};

void dfs(int x,int y,int no,char c)
{
    int i,xx,yy,tmp;
    for(i=0;i<4;i++)
    {
        xx=x+dx[i];
        yy=y+dy[i];
        if(xx<0||xx>=n||yy<0||yy>=m) continue;
        if(mp[xx][yy]==c)
        {
            if(num[xx*m+yy]==-1)//没有搜过的连通点
            {
                num[xx*m+yy]=no;
                dfs(xx,yy,no,c);
            }
        }
        else if(num[xx*m+yy]!=-1)//没有搜过的相邻不同颜色的点
        {
            tmp=num[xx*m+yy];
            v[no].push_back(tmp);
            v[tmp].push_back(no);
        }
    }
}

int bfs(int no)
{
    queue<node> q;
    node tmp,now;
    tmp.d=0;
    tmp.id=no;
    q.push(tmp);
    int ret=0;
    memset(vis,0,sizeof vis);
    vis[tmp.id]=1;
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        if(ret<now.d) ret=now.d;
        tmp.d=now.d+1;
        for(int j=0;j<v[now.id].size();j++)
        {
            tmp.id=v[now.id][j];
            if(!vis[tmp.id])
            {
                vis[tmp.id]=1;
                q.push(tmp);
            }
        }
    }
    return ret;
}

int main()
{
    int t,i,j,ans;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=0;i<n;i++)
            scanf("%s",mp[i]);

        for(i=0;i<=n*m;i++)
            v[i].clear();
        memset(num,-1,sizeof num);

        cnt=0;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                if(num[i*m+j]==-1)
                {
                    num[i*m+j]=cnt;
                    dfs(i,j,cnt,mp[i][j]);
                    cnt++;
                }
            }
        }
        ans=inf;
        for(i=0;i<cnt;i++)
            ans=min(ans,bfs(i));
        printf("%d\n",ans);
    }
    return 0;
}