zoj3781 Paint the Grid Reloaded --- 缩点 bfs

2024-05-28 10:58

本文主要是介绍zoj3781 Paint the Grid Reloaded --- 缩点 bfs,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

╮(╯▽╰)╭水题

相连的相同色块缩成点,和相邻的不同色块建边。

以每一个点为起点bfs,求最小答案。


题意:

给一个n*mX O构成的格子(其实给的是n*n,但处理时都当做n*m,真是奇怪啊),对一个点操作可以使与它相连通的所有一样颜色的格子翻转颜色(X>OO>X),问给定的矩阵最少操作多少次可以全部变成一样的颜色。

思路:

每次操作都将本身所在的连通块与和自己相邻的不同颜色的连通块变成同一种颜色,也就是变成一个连通块了,那么要使n次操作后全部变成一样的颜色,也就是从某点出发到达其余所有点。

dfs把连通块缩成点,然后相邻的连通块之间建边,枚举以每个点为根的情况,bfs求出每种情况的深度,取最小的即为答案。



#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#define ll long long
#define mod 1000000007
using namespace std;char mp[45][45];
int num[1610],cnt,n,m,vis[1610];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
vector<int> v[1600];struct node
{int d,id;
};void dfs(int x,int y,int no,char c)
{int i,xx,yy,tmp;for(i=0;i<4;i++){xx=x+dx[i];yy=y+dy[i];if(xx<0||xx>=n||yy<0||yy>=m) continue;if(mp[xx][yy]==c){if(num[xx*m+yy]==-1)//没有搜过的连通点{num[xx*m+yy]=no;dfs(xx,yy,no,c);}}else if(num[xx*m+yy]!=-1)//没有搜过的相邻不同颜色的点{tmp=num[xx*m+yy];v[no].push_back(tmp);v[tmp].push_back(no);}}
}int bfs(int no)
{queue<node> q;node tmp,now;tmp.d=0;tmp.id=no;q.push(tmp);int ret=0;memset(vis,0,sizeof vis);vis[tmp.id]=1;while(!q.empty()){now=q.front();q.pop();if(ret<now.d) ret=now.d;tmp.d=now.d+1;for(int j=0;j<v[now.id].size();j++){tmp.id=v[now.id][j];if(!vis[tmp.id]){vis[tmp.id]=1;q.push(tmp);}}}return ret;
}int main()
{int t,i,j,ans;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(i=0;i<n;i++)scanf("%s",mp[i]);for(i=0;i<=n*m;i++)v[i].clear();memset(num,-1,sizeof num);cnt=0;for(i=0;i<n;i++){for(j=0;j<m;j++){if(num[i*m+j]==-1){num[i*m+j]=cnt;dfs(i,j,cnt,mp[i][j]);cnt++;}}}ans=inf;for(i=0;i<cnt;i++)ans=min(ans,bfs(i));printf("%d\n",ans);}return 0;
}


这篇关于zoj3781 Paint the Grid Reloaded --- 缩点 bfs的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1010376

相关文章

hdu1254(嵌套bfs,两次bfs)

/*第一次做这种题感觉很有压力,思路还是有点混乱,总是wa,改了好多次才ac的思路:把箱子的移动当做第一层bfs,队列节点要用到当前箱子坐标(x,y),走的次数step,当前人的weizhi(man_x,man_y),要判断人能否将箱子推到某点时要嵌套第二层bfs(人的移动);代码如下:

poj 2195 bfs+有流量限制的最小费用流

题意: 给一张n * m(100 * 100)的图,图中” . " 代表空地, “ M ” 代表人, “ H ” 代表家。 现在,要你安排每个人从他所在的地方移动到家里,每移动一格的消耗是1,求最小的消耗。 人可以移动到家的那一格但是不进去。 解析: 先用bfs搞出每个M与每个H的距离。 然后就是网络流的建图过程了,先抽象出源点s和汇点t。 令源点与每个人相连,容量为1,费用为

POJ 3057 最大二分匹配+bfs + 二分

SampleInput35 5XXDXXX...XD...XX...DXXXXX5 12XXXXXXXXXXXXX..........DX.XXXXXXXXXXX..........XXXXXXXXXXXXX5 5XDXXXX.X.DXX.XXD.X.XXXXDXSampleOutput321impossible

深度优先(DFS)和广度优先(BFS)——算法

深度优先 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访

LibSVM学习(六)——easy.py和grid.py的使用

我们在“LibSVM学习(一)”中,讲到libSVM有一个tools文件夹,里面包含有四个python文件,是用来对参数优选的。其中,常用到的是easy.py和grid.py两个文件。其实,网上也有相应的说明,但很不系统,下面结合本人的经验,对使用方法做个说明。        这两个文件都要用python(可以在http://www.python.org上下载到,需要安装)和绘图工具gnup

GUI编程08:画笔paint

本节内容视频链接:10、画笔paint_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1DJ411B75F?p=10&vd_source=b5775c3a4ea16a5306db9c7c1c1486b5 package com.yundait.lesson03;import java.awt.*;import java.awt.event.Wind

双头BFS

牛客月赛100 D题,过了80%数据,调了一下午。。。烦死了。。。 还是没调试出来,别人的代码用5维的距离的更新有滞后性,要在遍历之前要去重。。。 #include<bits/stdc++.h>using namespace std;const int N=2e3+10;char g[N][N];int dis[N][N],d1[N][N];int n,m,sx,sy;int dx

Knight Moves -uva 简单的BFS遍历

昨天刚学了BFS的遍历,在uva上找了个题敲了出来,感觉还不错,最近敲代码挺有手感的,希望这种状态保持下去 #include<iostream>#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_SIZE 10 + 5#define LEN 100 + 10using namespace std;in

【CF】D. Arthur and Walls(BFS + 贪心)

D题 解题思路就是每次检查2X2的方格里是否只有一个‘*’,如果有的话这个*就需要变成‘.’,利用BFS进行遍历,入队的要求是这个点为. 一开始将所有的'.'全部加入队列,如果碰到一个'*'变成'.'就入队,判断的时候从4个方向就行判断 题目链接:http://codeforces.com/contest/525/problem/D #include<cstdio>#include<

hdu2717(裸bfs广搜)

Catch That Cow Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7304 Accepted Submission(s): 2308 题目链接: http://acm.hdu.edu.cn/showproblem.