///题意就是两个人在一个有草的地方放火,然后火的话呢 可以向4个方向蔓延,问两个人放火的时候,怎样才能够把草烧完使得所花时间最少(求时间)。
///因为这个点的个数比较少,所以呢咋们不妨一一进行枚举,找随机的两个点进行bfs直到所有的草全部烧完,在每次最大的里面求求一个最小值。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=1e1+7;
const int Max=1e6+7;
int n,m,vis[maxn][maxn];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
char mmp[maxn][maxn];
struct node
{
int x,y;
};
bool judge(int x,int y)///判断火的能不能继续烧下去。
{
if(x>=0&&x<=n-1&&y>=0&&y<=m-1&&mmp[x][y]=='#') return 1;
return 0;
}
int bfs(int x1,int y1,int x2,int y2)
{
memset(vis,Max,sizeof(vis));///这个本来想来一个标记的 后来感觉到最后它没有烧过的地方还得需要回去再重新查找一回。浪费时间。。
///下次再直接找的时候呢,直接判断有草的地方是不是无穷就可以了;
queue<node>Q;
node now,next;
now.x=x1;
now.y=y1;
next.x=x2;
next.y=y2;
vis[x1][y1]=0;
vis[x2][y2]=0;///因为这个开始的时候点火就相当于是已经把点火的地方点着了,不需时间。
Q.push(now);
Q.push(next);
while(!Q.empty())
{
now=Q.front();
Q.pop();
for(int i=0;i<4;i++)
{
int xx=now.x+dx[i];
int yy=now.y+dy[i];
///吐槽一个小坑点;本来是想着vis[xx][yy]==Max的时候,才将所有的情况走下去;
///不知道为什么,这个题写无穷就是过不了,后来想了一下 它可能存在一种两个火烧到同一个地方的时候,这个时候的话是不需要继续烧;
///烧完所有的草必须是取时间最长的。
if(judge(xx,yy)&&vis[xx][yy]>vis[now.x][now.y]+1)
{
vis[xx][yy]=vis[now.x][now.y]+1;
next.x=xx;
next.y=yy;
Q.push(next);
}
}
}
///找一个最大值;
int ans=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(mmp[i][j]=='#') ans=max(ans,vis[i][j]);
return ans;
}
int main ()
{
int t;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++)
{
scanf("%d %d",&n,&m);
int ans=Max;
for(int i=0;i<n;i++)
scanf("%s",mmp[i]);
///将所有有草的地方进行一一枚举;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(mmp[i][j]=='#')
{
for(int k1=0;k1<n;k1++)
{
for(int k2=0;k2<m;k2++)
{
if(mmp[k1][k2]=='#')
{
int ret=bfs(i,j,k1,k2);
ans=min(ret,ans);
//printf("%d\n",ans);
}
}
}
}
if(ans==Max) ans=-1;
printf("Case %d: %d\n",cas,ans);
}
return 0;
}
FZU - 2150 Fire Game
最新推荐文章于 2020-09-28 23:33:19 发布