foj 2150 Fire Games two-way wide search

foj 2150 Fire Games two-way wide search

Title

There is a piece of land of n*m, '#' represents the grass, and '.' Represents the open space; two people choose any point to start the fire (the points of the two people can overlap), only the grass can catch fire, and if there is grass up, down, left, and right Words can spread. The time from one piece of grass to another piece of grass is 1. Q: What is the shortest time for this piece of grass to completely catch fire?

note

Although the grass is on fire, it is not damaged-meaning that after a certain piece of grass is burned, fires in other places can still spread through here.

The two-way wide search of the topic means to start wide search from two points at the same time

Ideas

  1. First, BFS conducted a deep search to determine whether there are no more than two connected grasslands on this land, because there are at most two burning spots, and there may be a grassland that is isolated and not burned.
  2. Secondly, enumerate all possible starting points of two people, and start a breadth search at the same time (spreading like a fire), and use the book [] [] array mark to record the time of fire (there will be comments in the code) during the search, until the search end.
  3. Traverse the two-dimensional book [] [] array to find the maximum ignition time value.
  4. Continue to traverse other possible starting points for the two. Perform step 2 to know that all possible starting points are traversed.
  5. For all the maximum fire time values ​​found in step 3, find the minimum value.

撸Code:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
#define N 12/**行*/
#define M 12/**列*/
char s[N][M];/** 要搜索的图*/
struct node
{
    
    
    int x,y;
};
int book[N][M];/**标记数组*/
int n,m;
int dir[4][2]={
    
    0,1,1,0,0,-1,-1,0};
void dfs(int x,int y)/*深搜,每次深搜得到一个连通块*/
{
    
    
    book[x][y]=1;
    for(int i=0;i<4;i++)
    {
    
    
        int tx=x+dir[i][0];
        int ty=y+dir[i][1];
        if(tx<0||ty<0||ty>=m||tx>=n||s[tx][ty]=='.'||book[tx][ty])
            continue;
        book[tx][ty]=1;
        dfs(tx,ty);
    }
    return;
}

int bfs(int Sx,int Sy,int Tx,int Ty)/*S T 分别为两个人的起点*/
{
    
    
    node u,v;
    u.x=Sx; v.x=Tx;
    u.y=Sy; v.y=Ty;
    memset(book,0x3f3f3f3f,sizeof(book));
    queue<node>Q;
    Q.push(u);
    Q.push(v);/*同时加入队列,开始广搜*/
    book[Sx][Sy]=book[Tx][Ty]=0;/*事间初始值:本题从一块到另一块 时间才加1*/
    while(!Q.empty())
    {
    
    
        u=Q.front();
        Q.pop();
        for(int i=0;i<4;i++)
        {
    
    
            int tx=u.x+dir[i][0];
            int ty=u.y+dir[i][1];
            if(tx<0||ty<0||tx>=n||ty>=m||s[tx][ty]=='.'||book[tx][ty]<=book[u.x][u.y]+1)/*计算草地着火时间的最小值*/
                continue;
            book[tx][ty]=book[u.x][u.y]+1;)/*计算草地着火时间的最小值*/
            v.x=tx;
            v.y=ty;
            Q.push(v);
        }
    }
    int maxx=0;
    for(int i=0;i<n;i++)
    for(int j=0;j<m;j++)
    {
    
    
        if(s[i][j]=='#')
            maxx=maxx<book[i][j]?book[i][j]:maxx;/*找到该情况最大的着火时间值*/
    }
   // printf("%d %d ,%d %d maxx=%d\n",Sx,Sy,Tx,Ty,maxx);
    return maxx;
}

int main()
{
    
    
    int t;
    int Case=1;
    scanf("%d",&t);
    while(t--)
    {
    
    
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            scanf("%s",s[i]);

        int num=0;
        memset(book,0,sizeof(book));

        for(int i=0;i<n;i++)
        {
    
    
            for(int j=0;j<m;j++)
            {
    
    
                if(s[i][j]=='#'&&num<=2&&book[i][j]==0)
                {
    
    
                    num++;
                    dfs(i,j);/*寻找连通块*/
                }
            }
        }
        if(num>2)
        {
    
    
            printf("Case %d: -1\n",Case++);
            continue;
        }
        
        int ans=0x3f3f3f3f;
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(s[i][j]=='#')
                for(int u=0;u<n;u++)
                for(int v=0;v<m;v++)
                {
    
    
                    if(s[u][v]=='#')
                    {
    
    
                        memset(book,0,sizeof(book));
                        int temp=bfs(i,j,u,v);
                        ans=ans>temp?temp:ans;/*比较得出最优时间*/
                    }
                }
        printf("Case %d: %d\n",Case++,ans);
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/DREAM_yao/article/details/107990634