两点搜索 FZU - 2150 Fire Game 两点BFS

两点搜索 FZU - 2150 Fire Game 两点BFS

题意:
在一个木板上有许多方格,每一个方格里面放有不同的东西,一种是草用‘#’表示另一种是‘.’表示什么都没有,有两个人可以分别去点燃其中的一个方格里的草,然后每隔一分钟火势会蔓延到与他相邻的上下左右四个格。‘.’的地方火势不可以蔓延过去。
如果可以将里面的草全部烧完,要求解最小的时间是多少
否则 输出 -1;
思路:
最多只可以点两次火,所以如果草的堆数超过2则肯定不可以。
其余就是要求解符合规定时所用的最短时间。
1.用深搜判断是否符合只有小于等于两堆草的规定,不符合直接输出-1;
2.如果符合,则分两种情况 是一堆还是两堆(其实也没有必要分,但是代码是按分开写的,有兴趣自己可以尝试不分开的写法)分别用广搜求出最短时间即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<cmath>
using namespace std;
struct node{
    int xx,yy;
};
char mapp[15][15];
char map1[15][15];
int dist[15][15];
int vis[15][15];
int go[8]={1,0,-1,0,0,1,0,-1};
queue<node>qq[105];     //将可以点火的的节点放进队列,暴力枚举即可得到答案 
void dfs(int x,int y,int nn,int mm,int cc){
    node temp;
    temp.xx=x;temp.yy=y;
    qq[cc].push(temp);
    map1[x][y]='.';
    for(int i=0;i<8;i+=2){
        int xx=x+go[i];
        int yy=y+go[i+1];
        if(map1[xx][yy]=='#'&&xx>=1&&xx<=nn&&yy>=1&&yy<=mm){
            dfs(xx,yy,nn,mm,cc);
        }
    }
    return ;
}
int bfs(int x,int y,int nn,int mm){     //普通广搜
    int maxx=-1;
    memset(dist,0,sizeof(dist));
    memset(vis,0,sizeof(vis));
    node now,temp;
    now.xx=x;now.yy=y;
    queue<node>q;
    //cout<<q.size()<<endl;
    q.push(now);
    dist[now.xx][now.yy]=0;
    vis[now.xx][now.yy]=1;
    while(!q.empty()){
        now=q.front();
        q.pop();
        for(int i=0;i<8;i+=2){
            temp.xx=now.xx+go[i];
            temp.yy=now.yy+go[i+1];
            //cout<<map1[temp.xx][temp.yy]<<endl;
            if(!vis[temp.xx][temp.yy]&&temp.xx>=1&&temp.xx<=nn&&temp.yy>=1&&temp.yy<=mm&&map1[temp.xx][temp.yy]=='#'){
                dist[temp.xx][temp.yy]=dist[now.xx][now.yy]+1;
                if(maxx<=dist[temp.xx][temp.yy]){
                    maxx=dist[temp.xx][temp.yy];
                }
                q.push(temp);
                vis[temp.xx][temp.yy]=1;
            }
        }
    }
    return maxx;
}
int bfs_tp(node a,node b,int nn,int mm){    //两点广搜,其实没什么区别,只需要一次性加入两个点就好了
    memset(vis,0,sizeof(vis));
    memset(dist,0,sizeof(dist));
    int maxx=-1;
    queue<node>q;
    while(!q.empty())
    q.pop();
    q.push(a);
    q.push(b);
    vis[a.xx][a.yy]=1;
    vis[b.xx][b.yy]=1;
    while(!q.empty()){
        node now,temp;
        now=q.front();
        q.pop();
        for(int i=0;i<8;i+=2){
            temp.xx=now.xx+go[i];
            temp.yy=now.yy+go[i+1];
            if(!vis[temp.xx][temp.yy]&&temp.xx>=1&&temp.yy>=1&&temp.xx<=nn&&temp.yy<=mm&&map1[temp.xx][temp.yy]=='#'){
                dist[temp.xx][temp.yy]=dist[now.xx][now.yy]+1;
                maxx=max(maxx,dist[temp.xx][temp.yy]);
                q.push(temp);
                vis[temp.xx][temp.yy]=1;
            }
        }
    }
    return maxx;
}
int main()
{
    int t,cnt=0;
    int n,m;
    scanf("%d",&t);
    while(t--){
        int c=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%s",mapp[i]+1);
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                map1[i][j]=mapp[i][j];
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(map1[i][j]=='#'){
                    c++;
                    dfs(i,j,n,m,c);
                }
            }
        }
        //cout<<c<<endl;
        if(c>2){
            printf("Case %d: -1\n",++cnt);
        }
        else{
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    map1[i][j]=mapp[i][j];
                }
            }
            int ans1=0x3f3f3f,ans2=0x3f3f3f,ans=0x3f3f3f;
            if(c==2){
                while(!qq[1].empty()){
                    node temp;
                    temp=qq[1].front();
                    ans1=min(ans1,bfs(temp.xx,temp.yy,n,m));
                    qq[1].pop();
                }
                //cout<<endl;
                //cout<<qq[2].size()<<endl;
                while(!qq[2].empty()){
                    node temp;
                    temp=qq[2].front();
                    ans2=min(ans2,bfs(temp.xx,temp.yy,n,m));
                    qq[2].pop();
                }
                //cout<<ans1<<" "<<ans2<<endl;
                ans=max(ans1,ans2);
                if(ans==-1)ans=0;
            }
            if(c==1){
                node tp[105];int kk=0;
                while(!qq[1].empty()){
                    tp[++kk]=qq[1].front();
                    qq[1].pop();
                }
                for(int i=1;i<=kk;i++){
                    for(int j=1;j<=kk;j++){
                        ans=min(ans,bfs_tp(tp[i],tp[j],n,m));
                        //cout<<ans<<endl;
                    }
                }
                if(ans==-1)ans=0;
            }
            if(c==0){
                ans=0;
            }
            printf("Case %d: %d\n",++cnt,ans);
        }
        for(int i=0;i<105;i++){
            while(!qq[i].empty()){
                qq[i].pop();
            }
        }
    }
    return 0;
}
//其余代码中的细节问题希望大家可以自己琢磨。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值