官方题解证明
先画一个很大的联通块颜色B
然后在上面的联通块里画一个较小的联通块颜色为W
然后在上面的联通块里画一个较小的联通块颜色为B
。。。
这样的画法一定能得到最优解。。。。
然后就变成求BWBWBW交替出现的最短路。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=55;
int n,m;
char ss[N][N];
int vis[N][N];
int dis[N][N];
int check(int a,int b){
if(a<0||b<0||a>=n||b>=m)return 0;
return 1;
}
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
queue<int>qq ;
void pri(int aa[N],int n){
for(int i=0;i<n;i++){
printf("%d%c",aa[i],i==n-1?'\n':' ');
}
}
int sou(int x,int y){
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
qq.push(x);qq.push(y);
dis[x][y]=0;
vis[x][y]=1;
while(!qq.empty()){
int u=qq.front();qq.pop();
int v=qq.front();qq.pop();
vis[u][v]=0;
for(int i=0;i<4;i++){
int uu=u+dir[i][0],vv=v+dir[i][1];
if(check(uu,vv)){
int tp=(ss[uu][vv]!=ss[u][v]);
if(dis[uu][vv]>dis[u][v]+tp){
dis[uu][vv]=dis[u][v]+tp;
if(!vis[uu][vv]){
vis[uu][vv]=1;
qq.push(uu);qq.push(vv);
}
}
}
}
}
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(ss[i][j]=='W'){
ans=max(ans,dis[i][j]);
}
else {
ans=max(ans,dis[i][j]+1);
}
}
}
// printf("%d %d %d\n",x,y,ans);
// for(int i=0;i<n;i++){
// pri(dis[i],m);
// }printf("\n");
return ans;
}
int main(){
#ifdef DouBi
freopen("in.cpp","r",stdin);
#endif // DouBi
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=0;i<n;i++){
scanf("%s",ss[i]);
}
int ans=n*m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
ans=min(ans,sou(i,j));
}
}
printf("%d\n",ans);
}
return 0;
}