题目链接
大致题意:
给你一个大小
n
∗
m
n*m
n∗m 且只有元素
O
/
X
O/X
O/X 的矩阵,有这样一种操作每次你点一个元素的时候,这个元素所在的联通块(颜色相同)就会翻转,问你最少经过几次操作可以将所有的元素变成颜色统一
解题报告:
1.
1.
1.对同一连通块区域的点进行缩点
2.
2.
2.建图,在新点中相邻的点建立一条有向图
3.
3.
3.对每个点进行深搜求最大深度(最大深度=最小反转次数)再取
m
i
n
min
min,
代码展示:
#include<bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
#define mem(a, b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = 45;
const int MOD = 1e9 + 7;
struct TMD{
int to,next;
}edge[maxn*maxn*100];
int cnt,head[maxn*maxn],n,m;
char mp[maxn][maxn];
int vis[maxn][maxn],vit[maxn][maxn];
bool vik[maxn*maxn],col[maxn*maxn][maxn*maxn];
int fx[]={0,0,1,-1},fy[]={1,-1,0,0};
void add(int from,int to){
edge[++cnt]={to,head[from]};head[from]=cnt;
}
void dfs1(int x,int y,int num){
vis[x][y]=num;
for(int i=0;i<4;i++){
int nowx=x+fx[i],nowy=y+fy[i];
if(nowx>=1&&nowx<=n&&nowy>=1&&nowy<=m&&mp[nowx][nowy]==mp[x][y]&&vis[nowx][nowy]==0){
dfs1(nowx,nowy,num);
}
}
}
void dfs2(int x,int y){
vit[x][y]=vis[x][y];
for(int i=0;i<4;i++){
int nowx=x+fx[i],nowy=y+fy[i];
if(nowx<1||nowx>n||nowy<1||nowy>m||vit[nowx][nowy]==vis[x][y]) continue;
if(mp[nowx][nowy]==mp[x][y]) dfs2(nowx,nowy);
else {
if(!col[vis[x][y]][vis[nowx][nowy]]) add(vis[x][y],vis[nowx][nowy]);
col[vis[x][y]][vis[nowx][nowy]]=true;
}
}
}
int dfs3(int now){
queue<pii>q;
q.push({now,0});
mem(vik,false);
vik[now]=true;
int Mx=INT_MIN;
while (!q.empty()){
pii p=q.front();q.pop();
Mx=max(Mx,p.second);
for(int i=head[p.first];i;i=edge[i].next){
int to=edge[i].to;
if(!vik[to]){
vik[to]=true;
q.push({to,p.second+1});
}
}
}
return Mx;
}
int main() {
ios::sync_with_stdio(NULL);cin.tie(NULL);cout.tie(NULL);
int T;
cin>>T;
while (T--) {
mem(vis,0);mem(vit,0);mem(head,0);mem(vik,false);mem(col,false);
cin>>n>>m;cnt=0;
for(int i=1;i<=n;i++) cin>>(mp[i]+1);
int num=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(!vis[i][j]){
dfs1(i,j,++num);
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(!vik[vis[i][j]]) {
vik[vis[i][j]]=true;
dfs2(i,j);
}
}
}
int ans=INT_MAX;
for(int i=1;i<=num;i++){
ans=min(ans,dfs3(i));
}
cout<<ans<<'\n';
}
return 0;
}