题目大意:字符一样并且相邻的即为连通。每次可翻转一个连通块X(O)的颜色,问至少改变几次使得图上所有字符都相等
题目思路:每次操作都将本身所在的连通块与和自己相邻的不同颜色的连通块变成同一种颜色,也就是变成一个连通块了,那么要使n次操作后全部变成一样的颜色,也就是从某点出发到达其余所有点。
所以,dfs把连通块缩成点,然后相邻的连通块之间建边,枚举以每个点为根的情况,求最短路。
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn=2000;
int n,m;
char mapp[50][50];
int vis[50][50];
int viss[maxn];
int belong[50][50];
int mmp[maxn][maxn];
struct node
{
int x,y;
}headd,tail;
struct edge
{
int v,nxt;
}edge[20000];
int cnt=0;
int head[20000];
void add_edge(int u,int v)
{
edge[cnt].v=v;
edge[cnt].nxt=head[u];
head[u]=cnt++;
}
int dir[4][2]={0,1,1,0,0,-1,-1,0};
int block=0;
void bfs(int x,int y)
{
headd.x=x;
++block;
headd.y=y;
vis[x][y]=1;
queue<node>q;
while(!q.empty())q.pop();
q.push(headd);
while(!q.empty())
{
headd=q.front();
q.pop();
belong[headd.x][headd.y]=block;
for(int i=0;i<4;i++)
{
tail.x=headd.x+dir[i][0];
tail.y=headd.y+dir[i][1];
if(tail.x<=n&&tail.y<=m&&tail.x>=1&&tail.y>=1)
{
if(vis[tail.x][tail.y]==0&&mapp[tail.x][tail.y]==mapp[x][y])
{
q.push(tail);
vis[tail.x][tail.y]=1;
}
}
}
}
}
struct nodee
{
int distance,point;
nodee(){}
nodee(int _point,int _distance)
{
point=_point;
distance=_distance;
}
friend bool operator <(nodee aa,nodee bb)
{
return aa.distance>bb.distance;
}
};
int dis[maxn];
int maxx=0;
void zyz(int u)
{
for(int i=1;i<=block;i++)
{
dis[i]=0x3f3f3f3f;
viss[i]=0;
}
dis[u]=0;
priority_queue<nodee>q;
while(!q.empty())
q.pop();
q.push(nodee(u,dis[1]));
while(!q.empty())
{
nodee now;
now=q.top();
q.pop();
if(viss[now.point]==1)
{
continue;
}
viss[now.point]=1;
for(int i=head[now.point];i!=-1;i=edge[i].nxt)
{
int v=edge[i].v;
if(viss[v]==0)
{
if(dis[v]>dis[now.point]+1)
{
dis[v]=dis[now.point]+1;
q.push(nodee(v,dis[v]));
}
}
}
}
maxx=0;
for(int i=1;i<=block;i++)
{
maxx=max(maxx,dis[i]);
}
}
int main ()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(mapp,0,sizeof(mapp));
memset(vis,0,sizeof(vis));
memset(viss,0,sizeof(viss));
memset(belong,0,sizeof(belong));
memset(mmp,0,sizeof(mmp));
block=0;
maxx=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf(" %c",&mapp[i][j]);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(vis[i][j]==0)
{
bfs(i,j);
}
}
}
memset(head,-1,sizeof(head));
cnt=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int k=0;k<4;k++)
{
int tx,ty;
tx=i+dir[k][0];
ty=j+dir[k][1];
if(tx>=1&&ty>=1&&tx<=n&&ty<=m)
{
if(belong[i][j]!=belong[tx][ty])
{
mmp[belong[i][j]][belong[tx][ty]]=1;
mmp[belong[tx][ty]][belong[i][j]]=1;
}
}
}
}
}
for(int i=1;i<=block;i++)
{
for(int j=1;j<=block;j++)
{
if(mmp[i][j]==1)
{
add_edge(i,j);
}
}
}
int answer=0x3f3f3f3f;
for(int i=1;i<=block;i++)
{
zyz(i);
answer=min(answer,maxx);
}
printf("%d\n",answer);
}
}