FZU2150 - Fire Game - 双起点BFS
题意:
给出\(T\)组数据,每组数据给出\(N\)和\(M\),表示接下去\(N\)行\(M\)列。
图中“#”代表草,可以点燃;“.”点代表不能点燃;“#”和“.”都以走。
现在需要同时点两把火(位置可以重合),火的燃烧方向是上下左右,可以同时进行(注意!:不是一次只能一个方向,可以同时上下左右)。
若能烧完所有草(#),则输出最少时间,否则输出-1。
思路:
首先需要特判,如果草#的个数小于等于2的话,直接输出零(因为意味着点火的地方直接着了,无需耗费时间)。
否则,
因为是同时点燃两把火,所以相当于是双起点的BFS。
所以,我们先把草#用结构体存储起来,然后双for循环让每个草之间去进行一个BFS比较最短时间。
在BFS判断的时候,可以先让两个起点都入队,然后就是正常的BFS写法。
AC代码:
#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<list>
#include<stdlib.h>
#include<map>
#include<stack>
#include<stdio.h>
#include<queue>
using namespace std;
typedef long long ll;
#define sc(T) scanf("%d",&T)
#define scc(x,y) scanf("%d %d",&x,&y)
#define pr(T) printf("%d\n",T)
#define f(a,b,c) for (int a=b;a<=c;a++)
#define ff(a,b,c) for (int a=b;a>=c;a--)
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define eps 1e-9
#define PI acos(-1)
int n,m,p;
char a[12][12];
bool book[12][12];
int to[4][2]={{1, 0},{-1,0},{0, 1},{0, -1}};
//int to[4][2]={0,1,1,0,-1,0,0,-1};
struct node
{
int x,y,ss;
}e[110],pp,qq;
int bfs(node x,node y)
{
//book[x.x][x.y]=book[y.x][y.y]=1;
queue<node> Q;
x.ss=0,y.ss=0;
Q.push(x),Q.push(y);
book[x.x][x.y]=1;
book[y.x][y.y]=1;
// int ans=0;
int cnt=2;
while(!Q.empty())
{
pp=Q.front();
Q.pop();
// ans=pp.ss;
for(int i=0;i<4;i++)
{
qq=pp;
qq.x+=to[i][0];
qq.y+=to[i][1];
qq.ss+=1;
if(qq.x>=0&&qq.x<n&&qq.y>=0&&qq.y<m&&!book[qq.x][qq.y]&&a[qq.x][qq.y]!='.') //先判边界防止越界,或者单独写一个judge函数
{
book[qq.x][qq.y]=1;
cnt++;
Q.push(qq);
if(cnt==p) // 说明所有数量的草#(数量为p)已经全部点燃了
return qq.ss; // 返回最小步数,也就是最短时间。
}
}
}
// return ans;
return inf;
}
int main()
{
int T,cas=1;
sc(T);
while(T--)
{
scc(n,m);
p=0;
for(int i=0;i<n;i++)
{
scanf("%s",a[i]);
for(int j=0;j<m;j++)
{
if(a[i][j]=='#')// # grass
{
e[p].x=i;
e[p++].y=j;
}
}
}
if(p<=2)//特判 最多只有两个# 别忘了输出 不特判的话WA
{
printf("Case %d: 0\n",cas++);
continue;
}
int mi=inf;
for(int i=0;i<p;i++)
{
for(int j=i+1;j<p;j++)//0 save time
{
mem(book,0);
int w=bfs(e[i],e[j]);
mi=min(w,mi);
}
}
if(mi==inf)
printf("Case %d: -1\n",cas++);
else
printf("Case %d: %d\n",cas++,mi);
}
return 0;
}