zoukankan      html  css  js  c++  java
  • UVa 11624,两次BFS

    题目链接:http://vjudge.net/contest/132239#problem/A

    题目链接:https://uva.onlinejudge.org/external/116/11624.pdf

    《训练指南》P307

    分析:只需要预处理每个格子起火的时间,在BFS扩展节点的时候加一个判断,到达该节点的时候,格子没有起火。

    写法很巧妙,两次BFS类似,数据加一维kind,表示Joe到达该点和火到达该点。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    const int maxr = 1000+5;
    const int maxc = 1000+5;
    
    int R,C;
    char maze[maxr][maxc];
    struct Cell{
        int r,c;
        Cell (int r,int c) : r(r),c(c) {}
    };
    const int dr[] = {-1,1,0,0};
    const int dc[] = {0,0,-1,1};
    int d[maxr][maxc][2] ,vis[maxr][maxc][2];
    
    queue<Cell> Q;
    void bfs(int kind)
    {
        while(!Q.empty())
        {
            Cell cell = Q.front();
            Q.pop();
            int r = cell.r, c = cell.c;
            for(int dir = 0; dir < 4; dir++)
            {
                int nr = r + dr[dir], nc = c + dc[dir];
                if(nr >= 0 && nr < R && nc >= 0 && nc < C && maze[nr][nc] == '.' && !vis[nr][nc][kind])
                {
                    Q.push(Cell(nr, nc));
                    vis[nr][nc][kind] = 1;
                    d[nr][nc][kind] = d[r][c][kind] + 1;
                }
            }
        }
    }
    
    
    int ans;
    void check(int r,int c)
    {
        if(maze[r][c]!='.'||!vis[r][c][0]) return;      ///走不到
        if(!vis[r][c][1]||d[r][c][0]<d[r][c][1]) ans= min(ans,d[r][c][0]+1);    ///该点火到达不了,或者joe先于火
    }
    
    int main()
    {
        //freopen("input.txt","r",stdin);
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&R,&C);
            int jr,jc;
            vector<Cell> fires;
            for(int i=0;i<R;i++)
            {
                scanf("%s",maze[i]);
                for(int j=0;j<C;j++)
                {
                    if(maze[i][j]=='J')
                    {
                        jr = i;
                        jc = j;
                        maze[i][j] = '.';
                    }
                    else if(maze[i][j]=='F')
                    {
                        fires.push_back(Cell(i,j));
                        maze[i][j] = '.';
                    }
                }
            }
            memset(vis,0,sizeof(vis));
    
            ///各个点到joe的距离
            ///Joe
            vis[jr][jc][0] = 1;
            d[jr][jc][0] = 0;
            Q.push(Cell(jr,jc));
            bfs(0);
    
            for(int i = 0;i<fires.size();i++)
            {
                vis[fires[i].r][fires[i].c][1] = 1;
                d[fires[i].r][fires[i].c][1] = 0;
                Q.push(fires[i]);
            }
            bfs(1);
    
            ans = INF;
            for(int i=0;i<R;i++)
            {
                check(i,0);
                check(i,C-1);
            }
            for(int i=0;i<C;i++)
            {
                check(0,i);
                check(R-1,i);
            }
            if(ans==INF) printf("IMPOSSIBLE
    ");
            else printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    0705. Design HashSet (E)
    VMware简单使用
    Git笔记
    初识MyBatis
    数据库连接池配置 testOnBorrow
    Redis list操作命令
    文件/目录对比:diff命令
    可用于区块链的共识算法
    分布式一致性算法,你确定不了解一下?
    Jmeter文件下载测试
  • 原文地址:https://www.cnblogs.com/TreeDream/p/5874391.html
Copyright © 2011-2022 走看看