K - Fire Game
题目大意:给定一个图,‘.’表示空地,'#'表示草地。选择2块草地为放火点,火势每秒向上下左右蔓延。
开始时间为0,问所有草地被燃烧的最少时间。如果不能,则输出-1。
思路;枚举两个块草地u,v。然后以这两个点为原点进行bfs。dist[i][j]表示草地i到草地j的最短距离。dist[][]初始化为Inf。
那么每次枚举的两块草地u,v后,就对得到一张dist[][]的二维表,每次取所有草地i,j的dist[i][j]的最大值_max,如果存在dist[i][j],则表示该种枚举方式(u,v为源点)不能满足要求
最后取所有枚举(u,v)中_max的最小值为ans。
注意:如果草地的数量<=2,则输出0;
否则,若ans=inf,则为-1.
/**
author:liuwen
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <climits>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
const int inf=INT_MAX;
struct Node{
int x,y;
Node(int x=0,int y=0):x(x),y(y){};
};
int vis[15][15],G[15][15],dist[15][15];
vector<Node>v;
int n,m;
bool isok(int x ,int y)
{
if(x>=0&&x<n&&y>=0&&y<m) return true;
else return false;
}
void initial_Map()
{
scanf("%d%d",&n,&m);
char str[15];
memset(vis,0,sizeof(vis));
memset(G,0,sizeof(G));
v.clear();
for(int i=0;i<n;i++){
cin>>str;
for(int j=0;j<m;j++){
if(str[j]=='#') G[i][j]=1,v.push_back(Node(i,j));
}
}
}
int bfs(Node a,Node b)
{
for(int i=0;i<=n;i++){
fill(dist[i],dist[i]+m,inf);
}
queue<Node>que;
que.push(a);que.push(b);
dist[a.x][a.y]=0,dist[b.x][b.y]=0;
while(!que.empty()){
Node tmp=que.front();
que.pop();
for(int k=0;k<4;k++){
int nowX=tmp.x+dir[k][0];
int nowY=tmp.y+dir[k][1];
if(isok(nowX,nowY)&&G[nowX][nowY]){
if(dist[nowX][nowY]>dist[tmp.x][tmp.y]+1){
dist[nowX][nowY]=dist[tmp.x][tmp.y]+1;
que.push(Node(nowX,nowY));
}
}
}
}
int _min=-1000;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++) if(G[i][j])
_min=max(_min,dist[i][j]);
}
return _min;
}
int main()
{
//freopen("in.txt","r",stdin);
int T,cas=0;
scanf("%d",&T);
while(T--){
initial_Map();
int s=v.size();
if(s<=2){
printf("Case %d: 0\n",++cas);
continue;
}
int ans=inf;
for(int i=0;i<s;i++){
for(int j=i+1;j<s;j++){
ans=min(ans,bfs(v[i],v[j]));
}
}
if(ans==inf) printf("Case %d: -1\n",++cas);
else printf("Case %d: %d\n",++cas,ans);
}
return 0;
}