ZOJ 3781 Paint the Grid Reloaded(DFS连通块缩点+BFS求最短路)
题目链接: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求最短路)的更多相关文章
- 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 ...
- 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
枚举,$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 ...
- Paint the Grid Reloaded ZOJ - 3781 图论变形
Paint the Grid Reloaded Time Limit: 2000MS Memory Limit: 65536KB 64bit IO Format: %lld & %ll ...
- 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构成的格子,对 ...
- 图-用DFS求连通块- UVa 1103和用BFS求最短路-UVa816。
这道题目甚长, 代码也是甚长, 但是思路却不是太难.然而有好多代码实现的细节, 确是十分的巧妙. 对代码阅读能力, 代码理解能力, 代码实现能力, 代码实现技巧, DFS方法都大有裨益, 敬请有兴趣者 ...
随机推荐
- NOIWC前的交流题目汇总
RT 2018.12.27 i207M:BZOJ 4695 最假女选手 以维护最大值为例,记录最大值和严格次大值和最大值的出现次数,然后取min的时候递归到小于最大值但大于次大值修改,这个就是最重要的 ...
- bzoj 4028 : [HEOI2015]公约数数列
之前看了好几次都没什么思路,今天下定决心把这题切了. 观察到$0-x$的gcd最多变化log次,因为它每次变化一定至少要去掉一个质因子,所以我们可以枚举gcd. 因为数据范围比较小,所以想到了分块. ...
- (转)编码规范系列(一):Eclipse Code Templates设置
背景:长久以来,对java编程中的注释不甚理解.再次学习<疯狂JAVA讲义>基础,深深的感到自己基本功的不牢固.所以要做到事无巨细,好好修炼. 认识注释 常识 注释的作用: 回顾原有的代码 ...
- python之旅:并发编程之多进程理论部分
一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): egon在一个时间段内有很多任务要做:python备课的任务,写书的任 ...
- JavaScript匿名函数知多少
在一些Javascript库中可以看见这种写法: function(){ //所有库代码代码 }(); 这样写的一个目的是——封装. JavaScript并不是面向对象的,所以它不支持封装.但是在不支 ...
- 关于nodejs的几个干货(读中文文件编码问题/发送邮件/定时任务)
关于nodejs读取中文文件真是折腾了不少时间,网上各种方案,最后没有一个适用我,好在解决了. 下面的三个知识点都是从项目中抽出的,要单独运行脚本的话需要用全局模式来安装模块,比如安装中文转换模块(后 ...
- HDU 6040 stl
Hints of sd0061 Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- Nginx反向代理websocket配置实例
最近有一个需求,就是需要使用 nginx 反向代理 websocket,经过查找一番资料,目前已经测试通过,本文只做一个记录 复制代码 代码如下: 注: 看官方文档说 Nginx 在 1.3 以后的版 ...
- 使用traefik作为kubernetes的ingress
目录 说明 部署 创建一个独立的命名空间 配置rbac授权 配置secret 创建一个configmap用于存放traefik的配置文件 配置traefik的deployment文件 配置服务 通过p ...
- 科学计算三维可视化---TVTK入门(安装与测试)
推文:http://docs.huihoo.com/scipy/scipy-zh-cn/tvtk_intro.html 推文:http://code.enthought.com/pages/mayav ...