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

题目大意:字符一样并且相邻的即为连通。每次可翻转一个连通块X(O)的颜色,问至少改变几次使得图上所有字符都相等。

解题思路:

1) dfs( 建图 ) ,因为翻转的时候每翻转连通块中一个整个连通块都翻转,
这样你可以将其看成一个有边相连的无向图,每个边的两个顶点颜色都不一样。

2) bfs( 寻找最优解 ) , 建完图后就需要翻转计算最优解,可以枚举从每一点开始翻转所得到的最小步数,那怎样寻找最小步数 ?
假如从 v 这个顶点出发,那么与 v 相邻的顶点颜色必定都与 v 相反,so~> 你只需要把 v的颜色翻转,
v与它相邻的所有顶点都是同一个颜色,这时可以把这些顶点看成一个连通块(顶点),再向四周扩展,
再次扩展时,周围的颜色必定与此连通块颜色相反,再将它变成与周围顶点相同的颜色,
这样又合并成为一个连通块……这样一直进行下去取最大步数。最后从最大步数中取出最小的步数即为最优解。

代码:

 #include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<string>
#define lc(a) (a<<1)
#define rc(a) (a<<1|1)
#define MID(a,b) ((a+b)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define clr(arr,val) memset(arr,val,sizeof(arr))
#define _for(i,start,end) for(int i=start;i<=end;i++)
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long LL;
const int N=+;
const int INF=0x3f3f3f3f;
const double eps=1e-; int n,m,cnt;
int path[N*N],vis[N][N];
int d[][]={,,,,,-,-,};
char mp[N][N];
vector<int>v[N*N]; bool judge(int x,int y){
if(x>=&&y>=&&x<=n&&y<=m&&!vis[x][y])
return true;
return false;
} void dfs(int x,int y){
vis[x][y]=cnt;
for(int i=;i<;i++){
int xx=x+d[i][];
int yy=y+d[i][];
if(judge(xx,yy)&&mp[x][y]==mp[xx][yy]){
dfs(xx,yy);
}
}
} int bfs(int st){
memset(path,-,sizeof(path));
queue<int>q;
q.push(st);
path[st]=;
while(!q.empty()){
int k=q.front();
q.pop();
for(int i=;i<v[k].size();i++){
int t=v[k][i];
if(path[t]==-){
path[t]=path[k]+;
q.push(t);
}
}
}
} int main(){
FAST_IO;
int t;
cin>>t;
while(t--){
memset(vis,,sizeof(vis));
cin>>n>>m;
for(int i=;i<=n*m;i++) v[i].clear();
for(int i=;i<=n;i++){
cin>>mp[i]+;
}
cnt=;
//找连通块,缩点
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(!vis[i][j]){
++cnt;
dfs(i,j);
}
}
}
//连通块间建边
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
for(int k=;k<;k++){
int xx=i+d[k][];
int yy=j+d[k][];
if(vis[xx][yy]!=vis[i][j]){
int t1=vis[i][j],t2=vis[xx][yy];
v[t1].push_back(t2);
}
}
}
}
//枚举每个连通块为起点,每次找出最大路径,找出这些最大路径中的最小值
int ans=INF;
for(int i=;i<=cnt;i++){
bfs(i);
int mmax=-INF;
for(int j=;j<=cnt;j++){
mmax=max(mmax,path[j]);
}
ans=min(ans,mmax);
}
cout<<ans<<endl;
}
return ;
}

ZOJ 3781 Paint the Grid Reloaded(DFS连通块缩点+BFS求最短路)的更多相关文章

  1. ZOJ 3781 - Paint the Grid Reloaded - [DFS连通块缩点建图+BFS求深度][第11届浙江省赛F题]

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 Time Limit: 2 Seconds      Me ...

  2. 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 ...

  3. ZOJ 3781 Paint the Grid Reloaded

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

  4. ZOJ - 3781 Paint the Grid Reloaded 题解

    题目大意: 给一个n*m的X O构成的格子,对一个点操作可以使与它相连通的所有一样颜色的格子翻转颜色(X—>O或O—>X),问给定的矩阵最少操作多少次可以全部变成一样的颜色. 思路: 1. ...

  5. ZOJ 3781 Paint the Grid Reloaded 连通块

    LINK:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 题意:n*m只由OX组成的矩阵,可以选择某一连通块变成另一 ...

  6. 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 ...

  7. Paint the Grid Reloaded ZOJ - 3781 图论变形

    Paint the Grid Reloaded Time Limit: 2000MS   Memory Limit: 65536KB   64bit IO Format: %lld & %ll ...

  8. 2014 Super Training #4 E Paint the Grid Reloaded --联通块缩点+BFS

    原题: ZOJ 3781 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 题意: 给一个n*m的X,O构成的格子,对 ...

  9. 图-用DFS求连通块- UVa 1103和用BFS求最短路-UVa816。

    这道题目甚长, 代码也是甚长, 但是思路却不是太难.然而有好多代码实现的细节, 确是十分的巧妙. 对代码阅读能力, 代码理解能力, 代码实现能力, 代码实现技巧, DFS方法都大有裨益, 敬请有兴趣者 ...

随机推荐

  1. 设计模式之单例模式实现(C++)

    #ifndef SINGLETON_H #define SINGLETON_H #include <cassert> #include <memory> #include &l ...

  2. (转)Python中的generator详解

    本文转自:http://www.cnblogs.com/xybaby/p/6322376.html 作者:xybaby 注:本文在原文基础上做了一点点修改,仅仅作为个人理解与记忆,建议直接查看原文. ...

  3. mac python2.7.10 升级到 3.6

    第一步: 下载当前最新版本 Python3.6,下载地址:https://www.python.org/downloads/ 第二步: 安装下载好的包,安装完成后的目录如下: /Library/Fra ...

  4. 【精选】Nginx负载均衡学习笔记(一)实现HTTP负载均衡和TCP负载均衡(官方和OpenResty两种负载配置)

    说明:很简单一个在HTTP模块中,而另外一个和HTTP 是并列的Stream模块(Nginx 1.9.0 支持) 一.两个模块的最简单配置如下 1.HTTP负载均衡: http { include m ...

  5. [Luogu 3398] 仓鼠找sugar

    [Luogu 3398] 仓鼠找sugar 又是 LCA- 前两天死活写不过的一个题今天终于顺手切了. 思路嘛参考了一楼题解. 就是说,对于 a, b, c, d 四个点, 令 x = LCA(a, ...

  6. jmeter上传图片附件-小插曲

    背景 最近,接到新项目的接口测试,发现该接口是需要上传图片,开始折腾了好久没有搞定,最后才发现st和sid,并不是作为请求实体,而是url的一部分,好吧,是我没有仔细 请求参数 { "con ...

  7. Java并发编程原理与实战三:多线程与多进程的联系以及上下文切换所导致资源浪费问题

    一.进程 考虑一个场景:浏览器,网易云音乐以及notepad++ 三个软件只能顺序执行是怎样一种场景呢?另外,假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而 ...

  8. soj1767.传纸条

    这道题目想了一会儿觉得不知道如何下手,上网看了下资料,原来这道是一道非常经典的题目. 设 f [ k ][ i ][ j ] 表示第 k 步,第 1 条路径走到第 i 行,第 2 条路径走到第 j 行 ...

  9. datagrid时间插件

    jquery easyui日期控件中,在页面里用JS拿到设立的日期值的方法 链接:http://blog.csdn.net/liweibin_/article/details/13509917 jqu ...

  10. 回顾一些较简单的dp题

    1.导弹拦截  (+贪心) 两问:一个导弹拦截系统最多能拦多少导弹 要拦截所有导弹至少需要多少拦截系统 第一问感觉是一个比较巧妙的方法: 维护一个单调递减的序列 length[] 记录的是拦截导弹的高 ...