zoukankan      html  css  js  c++  java
  • UVA11624 Fire!(BFS)

    题目链接

    分析:

    先用BFS将所有的火能到达的时间计算出来,然后再一次BFS,计算最短路径。要求人每到一个方格的时间,必须小于该方格的着火时间。直到走到边界。

    注意

    WA很多次。。后来想出来了。少考虑了一种情况,那就是人一开始就在边界的情况

    AC代码如下:

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <map>
    
    using namespace std;
    
    const int maxn = 1000 + 10;
    const int INF = 1<<27;
    
    struct node{
        int x, y, cur;
        node(int x, int y, int cur):x(x), y(y), cur(cur) {}
    };
    
    int dx[] = {1, -1, 0, 0};
    int dy[] = {0, 0, -1, 1};
    
    char G[maxn][maxn];
    bool vis[maxn][maxn];
    int cost[maxn][maxn], n, m;
    
    queue<node> q;
    
    void init(){
        memset(vis, false, sizeof(vis));
        while(!q.empty()) q.pop();
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                cost[i][j] = INF;
            }
        }
    }
    
    void init_fire_time(){
        while(!q.empty()){
            int x = q.front().x;
            int y = q.front().y;
            int t = q.front().cur;
            q.pop();
            for(int d=0; d<4; d++){
                int nx = x + dx[d];
                int ny = y + dy[d];
                if(nx >= 0 && ny >= 0 && nx < n && ny < m && !vis[nx][ny] && G[nx][ny] == '.'){
                    q.push(node(nx, ny, t+1));
                    vis[nx][ny] = true;
                    cost[nx][ny] = t+1;
                }
            }
        }
    }
    
    int bfs(int x, int y){
        while(!q.empty()) q.pop();
    
        q.push(node(x, y, 0));
        vis[x][y] = 1;
        while(!q.empty()){
            x = q.front().x;
            y = q.front().y;
            int t = q.front().cur;
            q.pop();
            for(int d=0; d<4; d++){
                int nx = x+dx[d];
                int ny = y+dy[d];
                if(nx>=0 && nx<n && ny>=0 && ny<m && G[nx][ny] == '.' && !vis[nx][ny] && t+1<cost[nx][ny]){
                    if(nx == 0 || ny == 0 || nx == n-1 || ny == m-1) return t+1;
                    q.push(node(nx, ny, t+1));
                    vis[nx][ny] = 1;
                }
            }
        }
        return -1;
    }
    
    int main(){
        int T, x, y;
        scanf("%d", &T);
        while(T--){
            scanf("%d%d", &n, &m);
            init();
            for(int i=0; i<n; i++) scanf("%s", G[i]);
    
            for(int i=0; i<n; i++){
                for(int j=0; j<m; j++){
                    if(G[i][j] == 'J') { x = i; y = j; }
                    else if(G[i][j] == 'F'){
                        q.push(node(i, j, 0));
                        vis[i][j] = true;
                        cost[i][j] = 0;
                    }
                }
            }
    
            init_fire_time();
    
            memset(vis, false, sizeof(vis));
    
            vis[x][y] = 1;
            if(x == 0 || y == 0 || x == n-1 || y == m-1) { printf("1\n"); continue; }
    
            int ans = INF;
            ans = bfs(x, y);
    
            if(ans == -1)
                printf("IMPOSSIBLE\n");
            else
                printf("%d\n",ans+1);
        }
    
        return 0;
    }
    View Code

    后来网上查了查。发现了一种其他的写法,不用单独考虑人一开始在边界的情况。那就是记录到达所有点的最短时间。然后找出边界点中到达时间最小的。然后我就按着思路把代码改了改。

    AC代码如下:

    View Code
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <map>
    
    using namespace std;
    
    const int maxn = 1000 + 10;
    const int INF = 1<<27;
    
    struct node{
        int x, y, cur;
        node(int x, int y, int cur):x(x), y(y), cur(cur) {}
    };
    
    int dx[] = {1, -1, 0, 0};
    int dy[] = {0, 0, -1, 1};
    
    char G[maxn][maxn];
    bool vis[maxn][maxn];
    int cost[maxn][maxn], n, m;
    int ans[maxn][maxn];
    
    queue<node> q;
    
    void init(){
        memset(vis, false, sizeof(vis));
        while(!q.empty()) q.pop();
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                cost[i][j] = INF;
                ans[i][j] = INF;
            }
        }
    }
    
    void init_fire_time(){
        while(!q.empty()){
            int x = q.front().x;
            int y = q.front().y;
            int t = q.front().cur;
            q.pop();
            for(int d=0; d<4; d++){
                int nx = x + dx[d];
                int ny = y + dy[d];
                if(nx >= 0 && ny >= 0 && nx < n && ny < m && !vis[nx][ny] && G[nx][ny] == '.'){
                    q.push(node(nx, ny, t+1));
                    vis[nx][ny] = true;
                    cost[nx][ny] = t+1;
                }
            }
        }
    }
    
    void bfs(int x, int y){
        while(!q.empty()) q.pop();
    
        q.push(node(x, y, 0));
        vis[x][y] = 1;
        while(!q.empty()){
            x = q.front().x;
            y = q.front().y;
            int t = q.front().cur;
            q.pop();
            for(int d=0; d<4; d++){
                int nx = x+dx[d];
                int ny = y+dy[d];
                if(nx>=0 && nx<n && ny>=0 && ny<m && G[nx][ny] == '.' && !vis[nx][ny] && t+1<cost[nx][ny]){
                    q.push(node(nx, ny, t+1));
                    vis[nx][ny] = 1;
                    ans[nx][ny] = t+1;
                }
            }
        }
    }
    
    int main(){
        int T, x, y;
        scanf("%d", &T);
        while(T--){
            scanf("%d%d", &n, &m);
            init();
            for(int i=0; i<n; i++) scanf("%s", G[i]);
    
            for(int i=0; i<n; i++){
                for(int j=0; j<m; j++){
                    if(G[i][j] == 'J') { x = i; y = j; ans[i][j] = 0; }
                    else if(G[i][j] == 'F'){
                        q.push(node(i, j, 0));
                        vis[i][j] = true;
                        cost[i][j] = 0;
                    }
                }
            }
    
            init_fire_time();
    
            memset(vis, false, sizeof(vis));
    
            vis[x][y] = 1;
            bfs(x, y);
    
            int Ans = INF;
            for(int i = 0;i < n;i++){
                Ans = min(Ans,ans[i][0]);
                Ans = min(Ans,ans[i][m-1]);
            }
            for(int i = 0;i < m;i++){
                Ans = min(Ans,ans[0][i]);
                Ans = min(Ans,ans[n-1][i]);
            }
    
            if(Ans == INF) printf("IMPOSSIBLE\n");
            else printf("%d\n",Ans+1);
        }
    
        return 0;
    }
  • 相关阅读:
    [BJWC2018]Border 的四种求法
    [51nod1847]奇怪的数学题
    [51nod1965]奇怪的式子
    [BZOJ3283]运算器
    [TJOI2015]概率论
    [SDOI2017]遗忘的集合
    [HDU5709]Claris Loves Painting
    [Atcoder AGC032C]Three Circuits
    [Atcoder ARC103D]Robot Arms
    [Atcoder AGC030C]Coloring Torus
  • 原文地址:https://www.cnblogs.com/tanhehe/p/3076467.html
Copyright © 2011-2022 走看看