UVA 11624 Fire

题目链接https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2671

题目大意:迷宫里有几个地方失火了,小J要赶快出去,出口就是迷宫的没有障碍物的边界地方,但是火势蔓延速度和小J的速度都是一秒一个并且只能走到相邻的格子。问小明能不能走出去,若能,最少多长时间?

解题思路:两次宽搜即可。先搜索火再搜索人,看人走到边界的时候用的时间是否比火少。由于火不止一处,因此将初始为火的地方全部push到队列中然后就和普通的搜索一样了。

代码:

const int maxn = 1010;
char maze[maxn][maxn];
int n, m;
struct cell{
    int i, j, t;
    cell(int x, int y): i(x), j(y), t(0) {}
    cell(int x, int y, int ti): i(x), j(y), t(ti) {}
};
vector<cell> fires;
int jarrti[maxn][maxn], farrti[maxn][maxn];
short vis[maxn][maxn];
queue<cell> q;

int bfsj(int ti, int tj){
    memset(vis, 0, sizeof(vis));
    memset(jarrti, 0x3f, sizeof(jarrti));
    while(!q.empty()) q.pop();
    vis[ti][tj] = 1; jarrti[ti][tj] = 0;
    cell u(ti, tj, 0);
    q.push(u);
    int ans = inf;
    while(!q.empty()){
        u = q.front(); q.pop(); 
        if((u.i == n - 1 || u.j == m - 1 || u.i == 0 || u.j == 0) && u.t < farrti[u.i][u.j])
            return u.t + 1;
        u.t++;
        for(int i = 0; i < 4; i++){
            cell v = u; v.i += iadd[i]; v.j += jadd[i];
            if(v.i >= n || v.j >= m || v.i < 0 || v.j < 0) continue;
            if(maze[v.i][v.j] == '#' || maze[v.i][v.j] == 'F') continue;
            if(!vis[v.i][v.j]){
                vis[v.i][v.j] = 1; jarrti[v.i][v.j] = v.t;
                q.push(v);
            }
        }
    }
    return ans < inf? ans: -1;
}
void bfsf(){
    memset(vis, 0, sizeof(vis));
    memset(farrti, 0x3f, sizeof(farrti));
    while(!q.empty()) q.pop();
    for(int i = 0; i < fires.size(); i++){
        int fi = fires[i].i, fj = fires[i].j;
        vis[fi][fj] = 1; q.push(cell(fi, fj, 0)); farrti[fi][fj] = 0;
    }
    while(!q.empty()){
        cell u = q.front(); q.pop();
        u.t++;
        for(int i = 0; i < 4; i++){
            cell v = u; v.i += iadd[i]; v.j += jadd[i];
            if(v.i >= n || v.j >= m || v.i < 0 || v.j < 0) continue;
            if(maze[v.i][v.j] == '#') continue;
            if(!vis[v.i][v.j]){
                vis[v.i][v.j] = 1; farrti[v.i][v.j] = v.t;
                q.push(v);
            }
        }
    }
}

int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        fires.clear();
        while(!q.empty()) q.pop();
        scanf("%d %d", &n, &m);
        int ji, jj;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                scanf(" %c", &maze[i][j]);
                if(maze[i][j] == 'F') fires.push_back(cell(i, j));
                if(maze[i][j] == 'J') ji = i, jj = j;
            }
        }
        bfsf();
        int ans = bfsj(ji, jj);
        if(ans == -1) puts("IMPOSSIBLE");
        else printf("%d\n", ans);
    }
}

 

posted @ 2017-08-11 20:00  EricJeffrey  阅读(136)  评论(0编辑  收藏  举报