题意:
      给你一个n*m的矩阵,上面只有两种字符,X或者O,每次可以同时改变相同颜色的一个连通块,上下左右连通才算连通,用最小的步数把这个图弄成全是X或者全是O,题意要是没看懂看下面的样例。
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

思路:
      这个可以用最短路来做(也可以直接广搜,因为是在格子上找距离),首先我们要把每一个连通块缩成一个点,然后把相邻的联通快之间建边,然后枚举每一个点为起点,跑单源最短路,然后对于每一个点的当前答案就是所有点中离他最远的那个,最后在在每一个最远的点钟找到最小的那个,为什么这么做是对的,我们就假设我们枚举的最短路的起点是中心点,我们从中心点往外扩,每一次绝对可以扩展一层,这

一层有两种扩展方式,改变中间或者改变要扩展的这层,画一下就理解了。。


#include<stdio.h>
#include<string.h>
#include<queue>
#include<map>#define N_node 1600 + 100
#define N_edge 2000000
#define INF 100000000using namespace std;typedef struct
{int to ,next ,cost;
}STAR;STAR E[N_edge];
int list[N_node] ,tot;
int s_x[N_node];
int mapp[50][50] ,n ,m;
int mk[50][50];
int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};
map<int ,map<int ,int> >kk;void add(int a ,int b ,int c)
{E[++tot].to = b;E[tot].cost = c;E[tot].next = list[a];list[a] = tot;
}int spfa(int s ,int n)
{for(int i = 0 ;i <= n ;i ++)s_x[i] = INF;int mark[N_node] = {0};mark[s] = 1;s_x[s] = 0;queue<int>q;q.push(s);while(!q.empty()){int xin ,tou;tou = q.front();q.pop();mark[tou] = 0;for(int k = list[tou] ;k ;k = E[k].next){xin = E[k].to;if(s_x[xin] > s_x[tou] + E[k].cost){s_x[xin] = s_x[tou] + E[k].cost;if(!mark[xin]) {mark[xin] = 1;q.push(xin);}}}}int now = 0;for(int i = 1 ;i <= n ;i ++)if(now < s_x[i]) now = s_x[i];return now;
}bool ok(int x ,int y ,int ys)
{return x >= 1 && x <= n && y >= 1 && y <= m && !mk[x][y] && mapp[x][y] == ys;}   void DFS(int x ,int y ,int now ,int ys)
{for(int i = 0 ;i < 4 ;i ++){int xx = x + dir[i][0];int yy = y + dir[i][1];if(ok(xx ,yy ,ys)){mk[xx][yy] = now;DFS(xx ,yy ,now ,ys);}}return ;
}int main ()
{int i ,j ,t;char str[50];scanf("%d" ,&t);while(t --){scanf("%d %d" ,&n ,&m);for(i = 1 ;i <= n ;i ++){scanf("%s" ,str);for(j = 1 ;j <= m ;j ++)mapp[i][j] = str[j-1] == 'X';}memset(mk ,0 ,sizeof(mk));int now = 0;for(i = 1 ;i <= n ;i ++)for(j = 1 ;j <= m ;j ++){if(mk[i][j]) continue;mk[i][j] = ++now;DFS(i ,j ,now ,mapp[i][j]);}kk.clear();memset(list ,0 ,sizeof(list)) ,tot = 1;for(i = 1 ;i <= n ;i ++)for(j = 1 ;j <= m ;j ++){if(i > 1){if(mk[i][j] != mk[i-1][j] && !kk[mk[i][j]][mk[i-1][j]]){kk[mk[i][j]][mk[i-1][j]] = 1;add(mk[i][j] ,mk[i-1][j] ,1);}}if(i < n){if(mk[i][j] != mk[i+1][j] && !kk[mk[i][j]][mk[i+1][j]]){kk[mk[i][j]][mk[i+1][j]] = 1;add(mk[i][j] ,mk[i+1][j] ,1);}}if(j > 1){if(mk[i][j] != mk[i][j-1] && !kk[mk[i][j]][mk[i][j-1]]){kk[mk[i][j]][mk[i][j-1]] = 1;add(mk[i][j] ,mk[i][j-1] ,1);}}if(j < m){if(mk[i][j] != mk[i][j+1] && !kk[mk[i][j]][mk[i][j+1]]){kk[mk[i][j]][mk[i][j+1]] = 1;add(mk[i][j] ,mk[i][j+1] ,1);}}}int ans = INF;for(i = 1 ;i <= now ;i ++){int tmp = spfa(i ,now);if(ans > tmp) ans = tmp;}printf("%d\n" ,ans);}return 0;
}

ZOJ 3781 最短路(想法好题目)相关推荐

  1. *【ZOJ - 3781】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 initi ...

  2. CF 144D Missile Silos [最短路+想法]

    题意: 给出一张图和图上的一个顶点,求距离这个点距离为s(最短距离)的顶点或边上的点总共有几个(边上的点要保证也是最短距离) 分析: 先用DIJ求出最短路 然后对所有顶点,距离为s的点都算上 枚举每条 ...

  3. ZOJ 3781 Paint the Grid Reloaded

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

  4. Paint the Grid Reloaded ZOJ - 3781

    点击打开链接 先把每个连通块都当做一个点 然后建图 然后对每一个点bfs得到一个最大深度 再取最小值 这样做是因为这个图是个二分图 每个点与其邻接点的颜色都不一样 #include <bits/ ...

  5. 0x61.图论 - 最短路

    目录 单源最短路径 一.Dijkstra算法 1.常用的优先队列优化 2.更优的线段树优化 3.最强的zkw线段树优化 二.SPFA算法 三.分层图最短路 1.(二维分层图)AcWing 340. 通 ...

  6. CF1473E Minimum Path(拆点+最短路)

    CF1473E Minimum Path description solution code description 题目链接 solution 看到 ∑i=1kwei\sum_{i=1}^kw_{e ...

  7. C语言中短路求值问题

    短路现象(一) 以下表达式就是短路现象的其中一种 x & y & z; 如果x为假,直接返回假:若x为真,则执行y:只有x和y都为真才执行z. 例子 我们来看以下代码,求想x, y, ...

  8. PKU 3013 Big Christmas Tree 最短路 spfa

    题意/Description:     Christmas is coming to KCM city. Suby the loyal civilian in KCM city is preparin ...

  9. ~~朴素dijkstra算法 (搜索与图论)(附模板题AcWing 849. Dijkstra求最短路 I)

    模板 时间复杂是 O(n2+m), n表示点数,m 表示边数 int g[N][N]; // 存储每条边 int dist[N]; // 存储1号点到每个点的最短距离 bool st[N]; // 存 ...

最新文章

  1. 三维场景图:用于统一语义、三维空间和相机的结构
  2. “昊论坛”热力来袭!一网打尽【微生物绝对定量】技术特色和应用
  3. element 使用阿里图标变形了_web前端大厂面试题(阿里云笔试篇)
  4. IIS7.0 网站发布页面显示 500 - 内部服务器错误。您要查找的资源有问题,无法显示...
  5. PHPExcel读取excel的多个sheet存入数据库
  6. nyist 541最强DE 战斗力
  7. CDN视频存储解决方案
  8. linux关闭mysql strict mode的方法介绍
  9. ad6怎么画电阻_德国人怎么学电机——浅谈电机模型(十七):同步电机(四)永磁电机(二)...
  10. Redis Command
  11. spring和mybatis整合代码
  12. 基于FFMPEG+Python实现大视频分隔+水印+合并片头片尾
  13. 计算机里的音乐怎么设置,声音和音频设备在电脑上如何设置 电脑无声的情况如何解决【详解】...
  14. C# 将Big5繁体转换简体GB2312的代码
  15. xp用户未授予用户在此计算机,未授予用户在此计算机上的请求登录类型的解决方法 win7XP共享打印机完美解决教程...
  16. 711气象雷达电路图
  17. mac 微信 QQ 截图 问题
  18. java二重积分_《University Calculus》-chaper13-多重积分-二重积分的引入
  19. 2022年哈工大秋季学期程序人生
  20. 用户为先:谷歌做好三件事

热门文章

  1. PHP成为首个在内核中嵌入加密库的编程语言
  2. IdentityServer4 实现 OAuth 2.0(密码模式 - HTTP Post 方式)
  3. LVS集群-DR负载均衡集群
  4. .net Forms身份验证不能用在应用的分布式部署中吗?
  5. vCloud Automation Center (vCAC) 6.0 (二)
  6. Oracle存储过程(增、删、改)写法
  7. linux下ssh登录PIX防火墙
  8. Tensorflow--Debug
  9. 用python中的cv2库打开摄像头
  10. python学习-----9.7-----GIL、死锁递归锁、信号量,event事件