Fire Game (广搜(技巧))

来源:互联网 发布:windows airplay 编辑:程序博客网 时间:2024/06/05 20:38

题目来源:https://vjudge.net/contest/159739#problem/I
【题意】
从两个起点(可相同)对n*m的矩阵进行染色,矩阵中存在两种状态,“.”和“#”,其中“#”可以被染色,向四周扩散,问,最少需要多少时间才可以把所有“#”染成“.”,若不能,输出-1。
【思路】
用vector记录两点坐标,同时压进队列,进行广搜,更新最小值。
【代码】

#include<map>#include<stack>#include<queue>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<iostream>#include<string>#define mem(a,b) memset(a,b,sizeof(a))using namespace std;typedef long long LL;int n,m;char s[13][13];bool vis[13][13];bool flag[13][13];int d[4][2]= {{0,-1},{0,1},{1,0},{-1,0}};struct pp{    int x,y,t;};bool check(int x,int y){    if(x<0||x>=n||y<0||y>=m||!flag[x][y])        return 0;    return 1;}int bfs(pp a,pp b){    queue<pp> q;    int ans;    flag[a.x][a.y]=flag[b.x][b.y]=0;    q.push(a),q.push(b);    while(!q.empty())    {        a=q.front();        q.pop();        ans=a.t;        for(int i=0; i<4; i++)        {            b.x=a.x+d[i][0];            b.y=a.y+d[i][1];            if(check(b.x,b.y))            {                b.t=a.t+1;                flag[b.x][b.y]=0;                q.push(b);            }        }    }    return ans;}int main(){    int T,cases=1;    scanf("%d",&T);    while(T--)    {        scanf("%d%d%*c",&n,&m);        for(int i=0; i<n; i++)        {            scanf("%s",s[i]);            for(int j=0; j<m; j++)            {                if(s[i][j]=='#')                    vis[i][j]=1;                else                    vis[i][j]=0;            }        }        vector<pp> v;        for(int i=0; i<n; i++)        {            for(int j=0; j<m; j++)            {                if(vis[i][j])                {                    v.push_back((pp)                    {                        i,j,0                    });                }            }        }        int sum=0x3f3f3f3f;        for(int i=0; i<v.size(); i++)        {            for(int j=i; j<v.size(); j++)            {                memcpy(flag,vis,sizeof(vis));                int f=0;                int ans=bfs(v[i],v[j]);                for(int p=0; p<n; p++)                {                    for(int pp=0; pp<m; pp++)                    {                        if(flag[p][pp])                        {                            f=1;                            break;                        }                    }                }                if(!f&&ans<sum)                {                    sum=ans;                }            }        }        sum==0x3f3f3f3f?printf("Case %d: -1\n",cases++):printf("Case %d: %d\n",cases++,sum);    }}
0 0
原创粉丝点击