ZOJ3781 Paint the Grid Reloaded(dfs,bfs,连通块缩点)

描述

Leo has a grid with N rows and M columns. All cells are painted with
either black or white initially.

Two cells A and B are called connected if they share an edge and they
are in the same color, or there exists a cell C connected to both A
and B.

Leo wants to paint the grid with the same color. He can make it done
in multiple steps. At each step Leo can choose a cell and flip the
color (from black to white or from white to black) of all cells
connected to it. Leo wants to know the minimum number of steps he
needs to make all cells in the same color.

Input

There are multiple test cases. The first line of input contains an
integer T indicating the number of test cases. For each test case:

The first line contains two integers N and M (1 <= N, M <= 40). Then N
lines follow. Each line contains a string with N characters. Each
character is either ‘X’ (black) or ‘O’ (white) indicates the initial
color of the cells.

Output

For each test case, output the minimum steps needed to make all cells
in the same color.

Sample Input

2
2 2
OX
OX
3 3
XOX
OXO
XOX

Sample Output

1
2

Hint

For the second sample, one optimal solution is:

Step 1. flip (2, 2)

XOX OOO XOX Step 2. flip (1, 2)

XXX XXX XXX

思路

先说题意,给出一个n*m的图,里面有两种图案,XO,现在你每次可以选一个点,然后可以把这个点所在的相同颜色的连通块变成相反的颜色,问最少操作几次,可以使这个矩阵的颜色变成一样的。

首先我们可以对每一个连通块进行建图,假设给出的图是这样:


那么转化之后,就会变成:

图来来自与网络,应该1~5还有一条边,图的作者忘了画。

因为我们是对连通块进行的建图,所以可以保证每两个点所代表的颜色都不一样。当我们从图上一点出发的时候,这个点所连接的所有的边肯定都是相反的颜色,所以这个点到他所连接的所有的边的操作次数应该是1,应为他们肯定能形成一个连通块,比如图上的点从0开始,0所连接的有1和3这个两个点,那么这0,1,3这三个点通过一次操作就可以变成同一个颜色,所以我们只需要从每个点进行BFS,处理出来需要进行多少次操作可以可以使整个图变成一个联通快,再从这些最大值中找出最小的就是答案

代码

#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <sstream>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#include<list>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define inf 999999999
typedef long long ll;
const int N=50;
int n,m;
int num[N][N];
char s[N][N];
int go[4][2]= {1,0,-1,0,0,1,0,-1};
int first[N*N],tot,cnt;
int vis[4*N*N];
struct edge
{
    int v,next;
} e[2*4*N*N];
void add_edge(int u,int v)
{
    e[tot].v=v;
    e[tot].next=first[u];
    first[u]=tot++;
}
void init()
{
    mem(num,-1);
    mem(first,-1);
    tot=0;
    cnt=0;
}
void dfs(int x,int y,int ct,char ch)
{
    for(int i=0; i<4; i++)
    {
        int xx=x+go[i][0];
        int yy=y+go[i][1];
        if(xx>=0&&xx<n&&yy>=0&&yy<=m)
        {
            if(s[xx][yy]==ch)
            {
                if(num[xx][yy]==-1)
                {
                    num[xx][yy]=ct;
                    dfs(xx,yy,ct,ch);
                }
            }
            else if(num[xx][yy]!=-1)
            {
                int u=ct,v=num[xx][yy];
                add_edge(u,v);
                add_edge(v,u);
            }
        }
    }
}
struct node
{
    int x,step;
};
int bfs(int x)
{
    mem(vis,0);
    vis[x]=1;
    int maxx=0;
    queue<node>q;
    node now,to;
    now.x=x,now.step=0;
    q.push(now);
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        maxx=max(maxx,now.step);
        int u=now.x;
        to.step=now.step+1;
        for(int i=first[u]; ~i; i=e[i].next)
        {
            int v=e[i].v;
            if(!vis[v])
            {
                vis[v]=1;
                to.x=v;
                q.push(to);
            }
        }
    }
    return maxx;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        init();
        for(int i=0; i<n; i++)
            scanf("%s",s[i]);
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                if(num[i][j]==-1)
                {
                    num[i][j]=cnt++;
                    dfs(i,j,cnt-1,s[i][j]);
                }
        int ans=inf;
        for(int i=0; i<cnt; i++)
        {
            int maxx=bfs(i);
            ans=min(ans,maxx);
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/riba2534/article/details/80075817
今日推荐