题目连接:题目
题目大意:就是你又两把火,去烧草场的草,火只能上下左右烧,问烧完的时间,如果不能烧完,则输出-1;
解题思路:这个题算是第一次接触到双向广搜把,我觉得是双向广搜,,,,,,,,,,
说题把,找出两个点就去烧,然后不管是一个草堆还是多个草堆,记录每次烧的个数如果tot等于草堆总数,则是成功,否则不能烧完,并且在烧完的时候记录时间,然后维持这个时间的最小值
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<queue>
using namespace std;
const int maxn = 10+5;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
string s[maxn];
int n,m;
int sz=0;
bool vis[maxn][maxn];
struct node{
int x;int y;int t;
node(){};
node(int xx,int yy,int tt):x(xx),y(yy),t(tt){};
};
struct Togo{
int x;int y;
}togo[200];
int bfs(int u,int v,int k){
int tot=0;
queue<node> Q;
while(!Q.empty()) Q.pop();
node a;
a.x=togo[u].x;
a.y=togo[u].y;
a.t=k;
vis[a.x][a.y]=1; //标记起点
Q.push(a);
node b;
b.x=togo[v].x;
b.y=togo[v].y;
b.t=k;
vis[b.x][b.y]=1; //标记起点
Q.push(b);
while(!Q.empty()){
node A=Q.front();
Q.pop();
tot++;
if(tot==sz) return A.t;
for(int i=0;i<4;i++){
int nx=A.x+dir[i][0];
int ny=A.y+dir[i][1];
if(nx <0 || ny < 0 || nx >=n || ny >= m || s[nx][ny]=='.' || vis[nx][ny]) continue;
Q.push(node(nx,ny,A.t+1));
vis[nx][ny]=1;
}
}
return 1e9+5;
}
int main(int argc, char const *argv[])
{
int t;
scanf("%d",&t);
for(int pp=1;pp<=t;pp++){
sz=0;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
cin>>s[i];
for(int j=0;j<m;j++)
{
if(s[i][j]=='#'){ //记录所有的草的个数
togo[sz].x=i;
togo[sz].y=j;
sz++;
}
}
}
int ans = 1e9+5;
int c=ans;
for(int i=0;i<sz;i++){
for(int j=i;j<sz;j++){
memset(vis,0,sizeof(vis)); //去烧所有的草堆不能重复
ans=min(ans,bfs(i,j,0));
}
}
printf("Case %d: %d\n",pp,ans==c?-1:ans);
}
return 0;
}