题意大概:从n*m(#代表草地)的地图上选两个起点点火,第一块草地不消耗时间,在下一秒可以烧向上下左右四块草地。问最少需要多少秒草地被烧光,不能被烧光输出-1.
思路:由于n和m比较小,枚举两个点火的起点求出烧光所需时间,求个最小值。
CODE:
//FZU2150
#include<stdio.h>
#include<queue>
#include<vector>
#include<string.h>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
char mp[20][20];
int vis[20][20];
int n,m;
struct node
{
int x,y,t;
};
int bfs(node a,node b)
{
memset(vis,0,sizeof(vis));
queue<node>q;
while(!q.empty()) q.pop();
vis[a.x][a.y]=vis[b.x][b.y]=1;
int ans=inf;
q.push(a);
q.push(b);
node c,d;
while(!q.empty())
{
c=q.front();
q.pop();
ans=c.t;
for(int i=0;i<4;i++)
{
d.x=c.x+dx[i];
d.y=c.y+dy[i];
d.t=c.t+1;
if(d.x>=0&&d.x<n&&d.y>=0&&d.y<m&&!vis[d.x][d.y]&&mp[d.x][d.y]=='#')
{
vis[d.x][d.y]=1;
q.push(d);
}
}
}
return ans;
}
int main()
{
int T,tt=0;
scanf("%d",&T);
while(T--)
{
vector<node>v;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",mp[i]);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mp[i][j]=='#')
{
v.push_back((node){i,j,0});
}
}
}
int ans=inf;
for(int i=0;i<v.size();i++)
{
for(int j=0;j<v.size();j++)
{
int tmp=bfs(v[i],v[j]);
int flag=1;
for(int k=0;k<n;k++)
{
for(int f=0;f<m;f++)
{
if(vis[k][f]==0&&mp[k][f]=='#')
{
flag=0;
break;
}
}
if(flag==0) break;
}
if(flag) ans=min(ans,tmp);
}
}
if(ans==inf) ans=-1;
printf("Case %d: %d\n",++tt,ans);
}
}