本题目是双起点BFS,第一次做,和一个起点的BFS差不多,只是需要将开始两个起点时间全赋值为0就可以
值得借鉴处理时间的方法:用初始化为无穷的数组记录节点时间,并且起到标志数组的作用
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
int time[15][15];//表示本次遍历,烧完节点的最小时间
//同时用时间限制节点入队起到标志数组的作用
char mapp[15][15];
int m,n;
int T,TT;
int t;//每次遍历的最小时间
//初值为inf,遍历失败赋值为-1
struct point
{
int x;
int y;
};
queue<point>que;
int step[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};
int bfs(int x1,int y1,int x2,int y2)//两个遍历起始点
{
memset(time,inf,sizeof(time));//每个节点烧完的最小时间初始化
point p1,p2;
p1.x=x1;
p1.y=y1;//起始点1
p2.x=x2;
p2.y=y2;
time[x1][y1]=time[x2][y2]=0;
que.push(p1);
que.push(p2);
while(!que.empty())
{
point cur=que.front();
que.pop();
for(int i=0; i<4; i++)
{
int xx=cur.x+step[i][0];
int yy=cur.y+step[i][1];
//xx和yy是下一个节点的可能坐标
if(xx>=0&&xx<n&&yy>=0&&yy<m&&mapp[xx][yy]=='#'&&time[xx][yy]>time[cur.x][cur.y]+1)
{
time[xx][yy]=time[cur.x][cur.y]+1;//更新当前节点最小时间
point nex;
nex.x=xx;
nex.y=yy;
que.push(nex);
}
}
}
//遍历完成后,每个节点都应该达到烧完此节点的最小时间
int maxx=0;//求每个节点最小时间的最大值为本次bfs的解
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(mapp[i][j]=='#')
maxx=max(time[i][j],maxx);
return maxx;
}
int main()
{
cin>>T;
TT=T;
while(T--)
{
while(!que.empty())
{
que.pop();
}
//初始化,将队列清空
cin>>n>>m;//n行m列
for(int i=0; i<n; i++)
cin>>mapp[i];
t=inf;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(mapp[i][j]=='#')
for(int ii=0; ii<n; ii++)
for(int jj=0; jj<m; jj++)
if(mapp[ii][jj]=='#')
{
int ans=bfs(i,j,ii,jj);//返回烧完的最小时间
t=min(ans,t);
}
//便利失败
if(t==inf)
t=-1;
cout<<"Case "<<TT-T<<": "<<t<<endl;
}
return 0;
}