這道題說白了,其實就是最短路徑問題,果斷用寬搜,但是我們這裏要注意的是,
這道題是兩個起點的寬搜,兩個同時搜,而不是分開搜,我本人就是因爲這個錯誤而做了很久的
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=20;
const int inf=0x3f3f3f3f;
char a[maxn][maxn];
//char b[maxn][maxn];
int step[maxn][maxn];
int usedtime=111111111;
int direction[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
int column,line;
int ans=0;
int grasses;
int cases=0;
struct wo{
int x;
int y;
};
queue<wo>p;
int fire(){
int grass=0,time=0;
while(p.size()){
struct wo help;//結構體的入隊需要結構體才能入隊
help=p.front();p.pop();
for(int i=0;i<4;i++){
int x1=help.x+direction[i][0],y1=help.y+direction[i][1];
if(x1<1||x1>line)continue;
if(y1<1||y1>column)continue;
if(a[x1][y1]=='.')continue;
if(step[x1][y1]<=step[help.x][help.y]+1)continue;//滿足條件才入隊
step[x1][y1]=step[help.x][help.y]+1;
wo help1;
help1.x=x1;help1.y=y1;
p.push(help1);
grass++;//計算燃燒的草的個數
time=max(step[x1][y1],time);//算時間
}
}
if(grass==grasses-2)return time;//看燃燒完沒有
else return 111111111;
}
int main()
{
int t;
cin>>t;
while(t--){
usedtime=111111111,grasses=0;
cin>>line>>column;
for(int i=1;i<=line;i++){
for(int j=1;j<=column;j++){
cin>>a[i][j];
if(a[i][j]=='#')grasses++;//計算草的個數
}
}
for(int i=1;i<=line;i++){
for(int j=1;j<=column;j++){
if(a[i][j]=='.')continue;//只從有草的地方開始燃燒
for(int s=1;s<=line;s++){
for(int l=1;l<=column;l++){
if(a[s][l]=='.')continue;
if(l<=column){
while(p.size())p.pop();
if(i!=s||j!=l){
//cout<<a[i][j]<<" "<<a[s][l]<<endl;
memset(step,inf,sizeof(step));
wo ll;
ll.x=i;ll.y=j;step[i][j]=0;
p.push(ll);
ll.x=s;ll.y=l;step[s][l]=0;
p.push(ll);
int ff=fire();
usedtime=min(usedtime,ff);
}
}
}
}
}
}
cout<<"Case"<<" "<<++cases<<": ";
if(usedtime!=111111111)
cout<<usedtime<<endl;
else cout<<-1<<endl;
}
}