【题意】给出一个m*n的图,‘#’表示草坪,‘ . ’表示空地,然后可以选择在任意的两个草坪格子点火,火每 1 s会向周围四个格子扩散,问选择那两个点使得燃烧所有的草坪花费时间最小?

【分析】这个题目如果考虑技巧的话有点难度,但是鉴于数据范围比较小,我们可以暴力枚举任意的草坪所在的点,然后两个点压进队列里面BFS,去一个满足条件的最小值即可。

【总结】此题就是简单bfs,然而两个点同在相同时间的处理却比较少见,我也是通过此题学习到了这一方法!继续爆搜剪枝吧!武运昌隆。

【AC代码】

#include <stdio.h>
#include <vector>
#include <queue>
#include <ctype.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 11;
const int inf = 1<<30;
char maze[maxn][maxn];
bool vis[maxn][maxn];
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
struct node{
   int x,y,time;
   node(){}
   node(int x,int y,int time):x(x),y(y),time(time){}
};
vector<node>v;
int n,m,ans;
int bfs(node a,node b)
{
    int cur_time = inf;
    memset(vis,0,sizeof(vis));
    queue<node>que;
    a.time=b.time=0;
    vis[a.x][a.y]=vis[b.x][b.y]=true;
    que.push(a);que.push(b);
    while(!que.empty())
    {
        a=que.front();
        que.pop();
        cur_time = a.time;
        for(int i=0;i<4;i++)
        {
            b.x=a.x+dir[i][0];
            b.y=a.y+dir[i][1];
            b.time=a.time+1;
            if(b.x>0&&b.x<=n&&b.y>0&&b.y<=m&&!vis[b.x][b.y]&&maze[b.x][b.y]=='#')
            {
                vis[b.x][b.y]=1;
                que.push(b);
            }
        }
    }
    return cur_time;
}
int main()
{
    int T,cas=1;
    scanf("%d",&T);
    while(T--)
    {
        v.clear();
        scanf("%d%d",&n,&m);
        ans = inf;
        for(int i=1;i<=n;i++)
        {
            getchar();
            for(int j=1;j<=m;j++)
            {
                scanf("%c",&maze[i][j]);
                if(maze[i][j]=='#')v.push_back(node(i,j,0));
            }
        }
        for(int i=0;i<(int)v.size();i++)
        {
            for(int j=i;j<(int)v.size();j++)
            {
                int tmp =bfs(v[i],v[j]);
                bool *** = true;
                for(int x=1;x<=n;x++)
                {
                    for(int y=1;y<=m;y++)
                    {
                        if(maze[x][y]=='#'&&!vis[x][y])
                        {
                            ***=false;
                            break;
                        }
                        if(!***)break;
                    }
                }
                if(***) ans = min(ans,tmp);
            }
        }
        printf("Case %d: ",cas++);
        if(ans==inf)
        {
            printf("-1\n");
        }
        else
        {
            printf("%d\n",ans);
        }
    }
    return 0;
}