点击打开链接
先把每个连通块都当做一个点 然后建图 然后对每一个点bfs得到一个最大深度 再取最小值
这样做是因为这个图是个二分图 每个点与其邻接点的颜色都不一样
using namespace std;
struct node
{
int v;
int next;
};
queue <int> que;
node edge[100000];
int book[50][50],e[2000][2000];
int first[2000],dis[2000];
int n,m,num,cnt;
char mp[50][50];
void dfs(int x,int y,char tp)
{
int next[4][2]={0,-1,-1,0,0,1,1,0};
int i,tx,ty;
for(i=0;i<4;i++)
{
tx=x+next[i][0];
ty=y+next[i][1];
if(tx<0||tx>n-1|ty<0||ty>m-1||book[tx][ty]!=0||mp[tx][ty]!=tp) continue;
book[tx][ty]=cnt;
dfs(tx,ty,tp);
}
return;
}
void addedge(int u,int v)
{
edge[num].v=v;
edge[num].next=first[u];
first[u]=num++;
return;
}
void build()
{
int next[4][2]={0,-1,-1,0,0,1,1,0};
int i,j,k,tx,ty;
memset(e,0,sizeof(e));
memset(first,-1,sizeof(first));
num=0;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
for(k=0;k<4;k++)
{
tx=i+next[k][0];
ty=j+next[k][1];
if(tx<0||tx>n-1||ty<0||ty>m-1) continue;
if(book[i][j]!=book[tx][ty]&&!e[book[i][j]][book[tx][ty]])
{
e[book[i][j]][book[tx][ty]]=e[book[tx][ty]][book[i][j]]=1;
addedge(book[i][j],book[tx][ty]);
addedge(book[tx][ty],book[i][j]);
}
}
}
}
return;
}
int bfs(int s)
{
int i,u,v,res;
while(!que.empty()) que.pop();
memset(dis,-1,sizeof(dis));
que.push(s);
dis[s]=0;
res=0;
while(!que.empty())
{
u=que.front();
que.pop();
for(i=first[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(dis[v]==-1)
{
dis[v]=dis[u]+1;
res=max(res,dis[v]);
que.push(v);
}
}
}
return res;
}
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]);
}
memset(book,0,sizeof(book));
cnt=0;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(!book[i][j])
{
cnt++;
book[i][j]=cnt;
dfs(i,j,mp[i][j]);
}
}
}
build();
ans=N;
for(i=1;i<=cnt;i++)
{
ans=min(ans,bfs(i));
}
printf("%d\n",ans);
}
return 0;
}