FZU2150 :Fire Game (双起点BFS)

传送门:点我

题意:“#”是草,"."是墙,询问能不能点燃俩地方,即点燃俩“#”,把所有的草烧完,如果可以,那么输出最小需要的时间,如果不行输出-1

思路:暴力BFS,看到n和m都不大,直接把每个“#”都存下来,每次加入2个点进广搜搜能否烧完,然后更新ans即可。

#include <cstdio>  
#include <cstring>  
#include <cmath>  
#include <cstdlib>  
#include <ctime>  
#include <iostream>  
#include <algorithm>  
#include <sstream>  
#include <string>  
#include <vector>  
#include <queue>  
#include <stack>  
#include <map>  
#include <set>  
#include <utility>  
#include <bitset> 
using namespace std;  
#define LL long long  
#define pb push_back  
#define mk make_pair  
#define pill pair<int, int>  
#define mst(a, b)    memset(a, b, sizeof a)  
#define REP(i, x, n)    for(int i = x; i <= n; ++i)
void closeio(){
    cin.tie(0);
       ios::sync_with_stdio(0);
}
struct note{
    int x,y,step;
}p,pos;
char ma[20][20];
int vis[20][20];
int n,m;
int go[4][2] = {{1,0},{-1,0},{0,-1},{0,1}};//四个方向
void init(){
    memset(vis,0,sizeof(vis));
}
bool check(int x,int y){
    if(x < 0 || x >= n || y < 0 || y >= m || vis[x][y] == 1){
        return false;
    }
    return true;
}//判断是否越界和已经访问过
bool judge(){
    for(int i = 0 ; i < n ; i ++){
        for(int j = 0 ; j < m ; j ++){
            if(ma[i][j] == '#' && !vis[i][j]){
                return false;
            }
        }
    }
    return true;
}//判断是否满足全都着火了 
int bfs(int x,int y,int a,int b){
    int sum = 0;
    queue<note>q;
    q.push((note){x,y,0});
    vis[x][y] = 1;
    q.push((note){a,b,0});
    vis[a][b] = 1;
    //把两个点都加入队列 
    while(!q.empty()){
        pos = q.front();
        sum = pos.step;//队列中最后一个点的step就是需要的步数 
        q.pop();
        for(int i = 0 ; i < 4 ;i ++){
            int dx = pos.x + go[i][0];
            int dy = pos.y + go[i][1];
            if(check(dx,dy) && ma[dx][dy] == '#'){
                p.x = dx;
                p.y = dy;
                p.step = pos.step + 1;
                q.push(p);
                vis[dx][dy] = 1;
            }
        }
    }
    return sum;
}
int main()
{
    int t,cas = 1;
    for(scanf("%d",&t);t--;){
        vector<note>v;
        scanf("%d %d",&n,&m);
        for(int i = 0 ; i < n ; i++){
            scanf("%s",ma[i]);
            for(int j = 0 ; j < m ; j ++){
                if(ma[i][j] == '#'){
                    p.x = i;p.y = j;p.step = 0;
                    v.push_back(p);
                }
            }
        }
        int ans = 10000000;
        for(int i = 0 ; i < v.size() ; i++){
            for(int j = i ; j < v.size() ; j ++){
                init();
                int a = bfs(v[i].x,v[i].y,v[j].x,v[j].y);
                if(judge()){
                    ans  = min(a,ans);
                }//如果都着火了,那么ans值取ans和这次广搜中小的那个 
            }
        }
        printf("Case %d: %d\n",cas++,ans == 10000000?-1:ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Esquecer/p/9013462.html
今日推荐