ZOJ 3781 - Paint the Grid Reloaded - [DFS连通块缩点建图+BFS求深度][第11届浙江省赛F题]
题目链接: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 <= 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
题意:
两个方格字符一样并且相邻的即为判断为连通,且连通具有传递性;
每次翻转,可以也必须翻转一个连通块的颜色(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);
}
}
ZOJ 3781 - Paint the Grid Reloaded - [DFS连通块缩点建图+BFS求深度][第11届浙江省赛F题]的更多相关文章
- ZOJ 3781 Paint the Grid Reloaded(BFS+缩点思想)
Paint the Grid Reloaded Time Limit: 2 Seconds Memory Limit: 65536 KB Leo has a grid with N rows ...
- ZOJ 3781 Paint the Grid Reloaded(DFS连通块缩点+BFS求最短路)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5268 题目大意:字符一样并且相邻的即为连通.每次可翻转一个连通块X( ...
- ZOJ 3781 Paint the Grid Reloaded
枚举,$BFS$,连通块缩点. 可以枚举一开始染哪个位置,然后逐层往外染色,看最多需要多少操作次数,也就是算最短距离.连通块缩点之后可以保证是一个黑白相间的图,且每条边的费用均为$1$,$BFS$即可 ...
- ZOJ - 3781 Paint the Grid Reloaded 题解
题目大意: 给一个n*m的X O构成的格子,对一个点操作可以使与它相连通的所有一样颜色的格子翻转颜色(X—>O或O—>X),问给定的矩阵最少操作多少次可以全部变成一样的颜色. 思路: 1. ...
- ZOJ 3781 Paint the Grid Reloaded 连通块
LINK:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 题意:n*m只由OX组成的矩阵,可以选择某一连通块变成另一 ...
- ZOJ 3781 Paint the Grid Reloaded(BFS)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 Leo has a grid with N rows an ...
- ZOJ 3780 - Paint the Grid Again - [模拟][第11届浙江省赛E题]
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3780 Time Limit: 2 Seconds Me ...
- ZOJ 3777 - Problem Arrangement - [状压DP][第11届浙江省赛B题]
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3777 Time Limit: 2 Seconds Me ...
- 图-用DFS求连通块- UVa 1103和用BFS求最短路-UVa816。
这道题目甚长, 代码也是甚长, 但是思路却不是太难.然而有好多代码实现的细节, 确是十分的巧妙. 对代码阅读能力, 代码理解能力, 代码实现能力, 代码实现技巧, DFS方法都大有裨益, 敬请有兴趣者 ...
随机推荐
- Oauth2.0(五):Authorization Code 授权
Authorization Code 方式适用于有自己的服务器的应用.之所以叫这个名字,是因为流程中引入了一个叫做 authorization code 的东西.这个东西是一个一次性的临时凭证,用来换 ...
- Git初级使用教程
什么是 Git? Git 是一款免费的.开源的.分布式的版本控制系统.旨在快速高效地处理无论规模大小的任何软件工程. 每一个 Git克隆 都是一个完整的文件库,含有全部历史记录和修订追踪能力,不依赖于 ...
- c# windows服务
参考:https://www.cnblogs.com/knowledgesea/p/3616127.html 序言 前段时间做一个数据迁移项目,刚开始用B/S架构做的项目,但B/S要寄存在IIs中,而 ...
- JavaScript之 for...in
for-in 可以用来枚举对象的属性,还有数组的索引,用法: 枚举对象属性 var o={name:'a',age:25,sex:'male'} for(var each in o){ console ...
- 【代码审计】CLTPHP_v5.5.3 前台任意文件上传漏洞
0x00 环境准备 CLTPHP官网:http://www.cltphp.com 网站源码版本:CLTPHP内容管理系统5.5.3版本 程序源码下载:https://gitee.com/chichu/ ...
- EventHandler中如何提升用户权限(模拟管理员权限)
不论是在工作流或是EventHandler中,我们经常希望模拟管理员权限,从而可以通过程序自定义列表项的权限. 在工作流中可以用如下代码来提升权限:(以下代码实现的功能是断开列表项所继承的权限,除管理 ...
- 【RF库测试】Encode String To Bytes&Decode Bytes To String& should be string&should be unicode string &should not be string
场景1:判断类型 r ${d} set variable \xba\xcb\xbc\xf5\xcd\xa8\xb9\xfd #核减通过 Run Keyword And Continue On Fail ...
- jquery 动态展示查询条件
<table class="queryTable" width="100%" > <tr> <td class="que ...
- lua中的字符串操作(模式匹配)
(一). 模式匹配函数在string库中功能最强大的函数是:string.find(字符串查找)string.gsub(全局字符串替换)string.gfind(全局字符串查找)string.gmat ...
- 微信小程序连续动画
<view animation="{{animationData}}" style="background:red;height:100rpx;width:100r ...