题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781

Time Limit: 2 Seconds      Memory Limit: 65536 KB

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 <= NM <= 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

题意:

两个方格字符一样并且相邻的即为判断为连通,且连通具有传递性;

每次翻转,可以也必须翻转一个连通块的颜色(X→O,O→X),问至少翻转几次可以使得给出的图变得所有方格颜色都一样。

题解:

若把所有连通块缩成一个点看待,那么整个n*m的grid可以变成一个无向二分图;

那么,我们在这个二分图上任取一个点作为出发点,假设这个点在集合L,它沿着一条边走到另一个集合R内的另一个点;

这种沿着一条边走一步的动作,可以看做起点代表的那个连通块翻转了颜色,变成了与终点代表的连通块一样的颜色;

更形象的,相当于该条边的起点并入了终点;

那么我们一直走,就相当于不断地翻转颜色,直到遍历完全部二分图上所有点,就相当于把整个grid都翻成了一个颜色。

那么,翻转次数相当于什么呢?显然就是走过的边数。

显然,我们如果规定好起点,令其深度d[st]=0,那么bfs不断一层层地求其相邻点的d[],

直到全部搜索完,所有d[i]中的最大值,就是以st为起点需要翻转几次才能颜色全部一样。

另外,枚举起点为从(1,1)到(n,m)进行一次dfs就能把所有连通块缩成点,并且建立起一个二分图,这个正确性是可以想见的。

同时,存图方面,本题会卡邻接矩阵,需要使用邻接表。

AC代码:

#include<bits/stdc++.h>
using namespace std; const int INF=0x3f3f3f3f;
const int maxn=;
const int maxm=; int n,m;
char grid[maxn][maxm]; //存储grid
int id[maxn][maxm]; struct Edge{
int u,v;
Edge(int u,int v){this->u=u,this->v=v;}
};
vector<Edge> E;
vector<int> G[maxn*maxm];
void init(int n)
{
E.clear();
for(int i=;i<=n;i++) G[i].clear();
}
void addedge(int u,int v)
{
E.push_back(Edge(u,v));
E.push_back(Edge(v,u));
int _size=E.size();
G[u].push_back(_size-);
G[v].push_back(_size-);
} int dr[]={,,,-};
int dc[]={,,-,}; void dfs(int nowr,int nowc,int i)
{
id[nowr][nowc]=i;
for(int k=;k<;k++)
{
int nxtr=nowr+dr[k];
int nxtc=nowc+dc[k]; if(!(<=nxtr && nxtr<=n && <=nxtc && nxtc<=m)) continue;
if(grid[nowr][nowc]==grid[nxtr][nxtc])
{
if(id[nxtr][nxtc]==) dfs(nxtr,nxtc,i);
}
else
{
if(id[nxtr][nxtc]!=)
{
int idnow=id[nowr][nowc], idnxt=id[nxtr][nxtc];
addedge(idnow,idnxt);
}
}
}
} int d[maxn*maxm];
bool vis[maxn*maxm];
int bfs(int st,int cnt)
{
memset(vis,,sizeof(vis)); int res=;
queue<int> q;
q.push(st);
vis[st]=;
d[st]=;
while(!q.empty())
{
int u=q.front();q.pop();
res=max(d[u],res);
for(int i=,_size=G[u].size();i<_size;i++)
{
int v=E[G[u][i]].v;
if(vis[v]) continue;
d[v]=d[u]+;
q.push(v);
vis[v]=;
}
} return res;
} int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%s",grid[i]+); //连通块编号 - O(n*m)
init(m*n);
memset(id,,sizeof(id));
int cnt=;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(id[i][j]!=) continue;
dfs(i,j,++cnt);
}
} //for(int i=1;i<=cnt;i++) {for(int j=1;j<=cnt;j++) printf("%d ",edge[i][j]); printf("\n");} //SPFA求单源最短路 - O((n*m)^2)
int ans=INF;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
ans=min(bfs(id[i][j],cnt),ans);
}
} printf("%d\n",ans);
}
}

最新文章

  1. .net Elasticsearch 学习入门笔记
  2. Java程序员:工作还是游戏,是该好好衡量一下了
  3. 配置cas
  4. C#中this的用法,你用过几种?
  5. MVC02
  6. Symbolic link and hard link的区别(linux)
  7. JAVA基础2——类初始化相关执行顺序
  8. npm 和bower之间的区别
  9. Leetcode 137 Single Number II 仅出现一次的数字
  10. css实现纯文字内容元素透明背景(兼容IE6)
  11. [No0000175]maven常用命令集合(收藏大全)
  12. 浅尝辄止之MongoDB
  13. JavaSE——TCP协议网络编程(二)
  14. Linux——多线程下解决生产消费者模型
  15. 将安卓手机短信导入到iPhone6 plus中
  16. typescript 不用import?
  17. spring boot2集成ES详解
  18. tomcat之组成结构
  19. android.webkit.WebView/WebViewClient/WebChromeClient
  20. 从SVN一键对比版本

热门文章

  1. 时间戳Id
  2. python commands模块在python3.x被subprocess取代
  3. CM和CDH的安装-进阶完成
  4. Redis /etc/redis.conf 常用配置
  5. Qt打包部署程序自动查找依赖DLL工具windeployqt
  6. Android 之 布局训练
  7. Effective Java (6) - 消除过期的对象引用
  8. 计算完成率 SQL
  9. jQuery缓存机制(四)
  10. SharpGL学习笔记(七) OpenGL的变换总结