Nightmare (bidirectional BFS)

N * M given a map, the map has a boy, a girl and two ghosts.

"." Character represents the road, the character "X" represents a wall, character "M" represents the position of the boy, the character "G" represents the position of the girl, the character "Z" indicates the position of the ghost.

The boy can move 3 per unit distance, every second girl can move a unit distance, boys and girls can only move in four directions.

Each ghost can expand the area occupied per unit distance two to four weeks, and ignoring the barrier wall, i.e. at k seconds after all the ghost Manhattan distance does not exceed the 2k locations will be occupied ghost.

Note: every second ghost will first expand, expand after completion of boys and girls can move.

Without seeking to enter the ghost of the occupied territories, boys and girls can join, if we meet, find the shortest possible time to meet.

Input Format

The first row contains an integer T, T represents a total set of test cases.

The first line of each test case contains two integers N and M, represents the size of the map.

Next N lines of M characters used to describe the condition of the entire map. (Note: the map must have one and only one boy, one girl and two ghost)

Output Format

Each test output an integer S, represents the shortest convergence time.

If you can not join the output -1.

Each result row.


emmmmm, at the time called the test program went back to class, and then come back to see my code in this thing:

 

 Ah ah ah, Meng God, your algorithm Advanced I did not really get ah.
Into the title--

Seeking a few steps, then it is easy to think of BFS, but this is two people, in fact, very easy to think of a two-way BFS, create two queues, while in search of a legitimate state, when people search for a person to another spot visited Point when, at this time the number of steps is a minimum number of steps;

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 5e5 + 100;
const int MAXM = 3e3 + 10;

template < typename T > inline void read(T &x) {
    x = 0; T ff = 1, ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-') ff = -1;
        ch = getchar();
    } 
    while(isdigit(ch)) {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    } 
    x *=ff;
} 

template < typename T > inline void write(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) write(x / 10); 
    putchar(x % 10 + '0'); 
} 

int T, n, m;
int vis [MaxM] [MaxM];
int dx [ 5 ] = { 1 , 0 , - 1 , 0 };
int values [ 5 ] = { 0 , 1 , 0 , - 1 };
char ch [MaxM] [MaxM];  
pair < int, int > boy, girl,  ghost[2];

// God Liang my advanced algorithm that is not in your - MSM 

inline BOOL the Check ( int xx, int YY, int DIS) {
     IF (xx < 0 || xx> = || the n-YY < 0 || YY > || m = CH [XX] [YY] == ' X- ' ) return  to false ;
     for ( int I = 0 ; I < 2 ; ++ I) {
         IF (ABS (XX - Ghost [I] .first) ABS + (YY - Ghost [I] .second) <= 2 * DIS) return  to false ;
    }
    return true;
}

inline int BFS() {
    memset(vis, 0, sizeof(vis));
    queue < pair < int, int > > qb, qg;
    qb.push(boy);
    qg.push(girl);
    int dis = 0;
    while(!qb.empty() || !qg.empty()) {
        ++dis;
        for(int i = 0; i < 3; ++i) {
            int len = qb.size();
            for(int j = 0; j < len; ++j) {
                pair < int, int > x;
                x = qb.front();
                qb.pop();
                int a = x.first, b = x.second;
                if(!check(a, b, dis)) continue;
                for(int k = 0; k < 4; ++k) {
                    int u = a + dx[k], v = b + dy[k];
                    if(check(u, v, dis)) {
                        if(vis[u][v] == 2) return dis;
                        if(!vis[u][v]) {
                            vis [u] [v] = 1 ;
                            qb.push({u, v});
                        }
                    }
                }
            }
        }
        int len = qg.size(); 
        for(int i = 0; i < len; ++i) {
            pair < int, int > x; 
            x = qg.front(); 
            qg.pop(); 
            int a = x.first, b = x.second; 
            if(!check(a, b, dis)) continue; 
            for(int k = 0; k < 4; ++k) { 
                int u = a + dx[k], v = b + dy[k]; 
                if(check(u, v, dis)) {
                    if(vis[u][v] == 1) return dis;
                    if(!vis[u][v]) {
                        vis [u] [v] = 2 ;
                        qg.push({u, v});
                    }
                }
            }
        }
        
    }
    return -1;
}

int main () {
    read(T);
    while(T--) {
        read(n); read(m);
        for(int i = 0; i < n; ++i) {
            scanf("%s", ch[i]);
        }
        int tot = 0;
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < m; ++j) {
                if(ch[i][j] == 'M') boy = {i, j};
                else if(ch[i][j] == 'G') girl = {i, j};
                else if(ch[i][j] == 'Z') ghost[tot++] = {i ,j};
            }
        }
        write(BFS());
        puts("");
    } 
    return 0;
} 

 

Guess you like

Origin www.cnblogs.com/AK-ls/p/11447289.html