题意:给你n*m的矩阵"#"代表草“.”代表空地,问两个人同时烧草,最小需要多少时间把草烧完(燃烧的草会蔓延到它的相邻的草)
思路:算出每颗草烧到所有草所需的时间,即ma[i][k][l];
从所有的草枚举两个i,j算出它烧完所需的时间;
在加一些初始判断优化下
#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<string>
//#include<map>
#include<cmath>
#include<iostream>
#include <queue>
#include <stack>
#include<algorithm>
#include<set>
using namespace std;
#define INF 1e8
#define inf -0x3f3f3f3f
#define eps 1e-8
#define ll __int64
#define maxn 250001
#define mol 100007
char mat[11][11];
int dx[4]={-1,0,0,1},k;
int dy[4]={0,1,-1,0};
int n,m;
int ma[110][11][11];//ma[i][k][l]表示第i棵草烧到(k,l)点草所需的时间
int vis[11][11];
struct point
{
int x,y,t;
}p[110][110];
bool pd(int x,int y)
{
if(x>=0&&x<n&&y>=0&&y<m&&mat[x][y]=='#')
return true;
return false;
}
void bfss(int x,int y,int id)
{
queue<point>T;
point a,b;
ma[id][x][y]=1;
a.x=x;a.y=y;a.t=1;
T.push(a);
p[id][k].x=x;p[id][k].y=y;
while(!T.empty ())
{
a=T.front ();
T.pop();
for(int i=0;i<4;i++)
{
int xx=a.x+dx[i];
int yy=a.y+dy[i];
if(pd(xx,yy)&&!ma[id][xx][yy])
{
ma[id][xx][yy]=a.t+1;
b.x=xx;b.y=yy;b.t=a.t+1;
T.push(b);
}
}
}
}
void bfs(int x,int y)
{
queue<point>T;
point a,b;
a.x=x;a.y=y;
T.push(a);
vis[x][y]=1;
while(!T.empty ())
{
a=T.front ();
T.pop();
for(int i=0;i<4;i++)
{
int xx=a.x+dx[i];
int yy=a.y+dy[i];
if(pd(xx,yy)&&vis[xx][yy]==0)
{
vis[xx][yy]=1;
b.x=xx;b.y=yy;
T.push(b);
}
}
}
}
int main()
{
int t,Case=1,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%s",mat[i]);
memset(ma,0,sizeof(ma));
memset(vis,0,sizeof(vis));
int num=0,k,l;
int tmp=0;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(mat[i][j]=='#')
{
bfss(i,j,num++);
if(vis[i][j]==0)
{
tmp++;
bfs(i,j);
}
}
}
}
printf("Case %d: ",Case++);
if(num<=2)//草的数量<=2
{
printf("0\n");
continue;
}
if(tmp>2) //草的分块>2
{
printf("-1\n");
continue;
}
int dis=0,ans=INF,flag=0;
for(i=0;i<num;i++)//枚举i,j两点开始烧
{
for(j=i;j<num;j++)
{
dis=0;flag=0;
for(k=0;k<n;k++)
{
for(l=0;l<m;l++)
{
if(mat[k][l]=='#')
{
if(ma[i][k][l]==0&&ma[j][k][l]==0)//关键:当i,j两点有烧不到的草,则说明i,j不行
{
flag=1;
break;
}
else if(ma[i][k][l]&&ma[j][k][l])//如果i,j两点都可以烧到(k,l)点的草则肯定t小的先烧到
{
int d=ma[i][k][l]>ma[j][k][l]?ma[j][k][l]:ma[i][k][l];
if(d>dis) dis=d;
}
else//最晚烧完的才算全部烧完
{
dis=max(ma[i][k][l],max(dis,ma[j][k][l]));
}
}
}
if(flag) break;
}
if(!flag&&dis<ans)
{
ans=dis;
}
}
}
printf("%d\n",ans-1);
}
return 0;
}