zoukankan      html  css  js  c++  java
  • codeforces 591 E. Three States(bfs+思维)

    题目链接:http://codeforces.com/contest/591/problem/E

    题意:有3个数字表示3个城市,每种城市都是相互连通的,然后不同种的城市不一定联通,'.'表示可以建设道路‘#’表示

    不能,问最短建设多少道路能够让3种城市都联通起来

    题解:直接bfs一遍所有类型的城市,bfs的同时更新第i类城市到(x,y)点的最短距离,更新第i类城市到第j类城市的距离

    具体看一下代码。

    #include <iostream>
    #include <cstring>
    #include <queue>
    #define inf 0X3f3f3f3f
    using namespace std;
    const int M = 1e3 + 10;
    char mmp[M][M];
    int n , m , dr[4][2] = {1 , 0 , -1 , 0  , 0 , 1 , 0 , -1};
    int dis[4][M][M] , de[4][4];//dis表示i种城市到(x,y)点的最短距离初始值为inf,de表示第i个城市到第j个城市的最短距离初始值为inf
    struct TnT {
        int x , y;
        TnT(){}
        TnT(int x , int y):x(x) , y(y) {}
    };
    void bfs(int num) {
        queue<TnT>q;
        for(int i = 0 ; i < n ; i++) {
            for(int j = 0 ; j < m ; j++) {
                if(mmp[i][j] == num + '0') {
                    q.push(TnT(i , j));
                    dis[num][i][j] = 0;
                }
            }
        }
        while(!q.empty()) {
            TnT gg = q.front();
            q.pop();
            char cp = mmp[gg.x][gg.y];
            if(cp != '.') {
                de[num][cp - '0'] = min(dis[num][gg.x][gg.y] - 1 , de[num][cp - '0']);//更新第num种到其他两种城市的距离
            }
            for(int i = 0 ; i < 4 ; i++) {
                TnT gl = gg;
                gl.x += dr[i][0] , gl.y += dr[i][1];
                if(gl.x >= 0 && gl.x < n && gl.y >= 0 && gl.y < m && mmp[gl.x][gl.y] != '#') {
                    if(dis[num][gl.x][gl.y] == inf) {
                        dis[num][gl.x][gl.y] = dis[num][gg.x][gg.y] + 1;//更新第num种城市到(x,y)点的距离,这里直接更新一次就行利用了bfs的特性,好好体会一下。
                        q.push(gl);
                    }
                }
            }
        }
    }
    int main() {
        cin >> n >> m;
        for(int i = 0 ; i < n ; i++) {
            cin >> mmp[i];
        }
        memset(dis , inf , sizeof(dis));
        memset(de , inf , sizeof(de));
        for(int i = 1 ; i <= 3 ; i++) {
            bfs(i);//遍历3种城市
        }
        int ans = de[1][2] + de[1][3];
        ans = min(de[1][2] + de[2][3] , ans);
        ans = min(de[1][3] + de[2][3] , ans);
        for(int i = 0 ; i < n ; i++) {
            for(int j = 0 ; j < m ; j++) {
                if(mmp[i][j] != '.') continue;
                if(dis[1][i][j] == inf || dis[2][i][j] == inf || dis[3][i][j] == inf) continue;
                ans = min(dis[1][i][j] + dis[2][i][j] + dis[3][i][j] - 2 , ans);
            }
        }
        //ans总共的情况就是要么3种城市链接起来要么在中间找一个点算一下到3种城市的距离
        if(ans >= inf) cout << -1 << endl;
        else cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    递归的形式过程
    c/c++程序员常见面试题分析(转)
    深入理解递归函数的调用过程(转)
    C语言union关键字
    中国象棋(java)
    求树中最低的公共祖先
    什么是Complement(补码)?
    LoadRunner,各协议之间的区别
    淘宝模板制作[店铺装修]学习过程+心得
    Tips of QTP
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6872827.html
Copyright © 2011-2022 走看看