• 洛谷P7297 [USACO21JAN] Telephone G 题解 分层图最短路


    题目链接:https://www.luogu.com.cn/problem/P7297

    解题思路:

    对于每个颜色 \(c\),在第 \(c\) 层作出一条链,对于 \(1 \le i \lt n\)\((i,c)\)\((i,c+1)\) 之间有一条权值为 \(1\) 的双向边。

    \((i,0)\)\((i, b_i)\) 连一条权值为 \(0\) 的有向边。

    对于所有 \(S_{c, b_i} = 1\) 的颜色 \(c\),从 \((i,c)\) 连向 \((i, 0)\) 一条权值为 \(0\) 的有向边。

    \((1, 0)\) 为起点 \((n, 0)\) 为终点求最短路。

    示例程序(需要开 O2 优化):

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 50050;
    
    int n, K, b[maxn], dis[maxn * 55];
    struct Edge {
        int v, w;
        Edge() {}
        Edge(int _v, int _w) { v = _v; w = _w; }
    };
    vector<Edge> g[maxn * 55];
    char color[55][55];
    bool vis[maxn * 55];
    
    struct Node {
        int u, dis;
        bool operator < (const Node& b) const {
            return dis > b.dis;
        }
    };
    priority_queue<Node> que;
    
    int ha(int u, int k) {
        return k * n + u;
    }
    
    int main() {
        ios::sync_with_stdio(0);
        cin.tie();
        cin >> n >> K;
        for (int i = 1; i < n; i ++) {
            for (int j = 1; j <= K; j ++) {
                g[ha(i, j)].push_back({ha(i+1, j), 1});
                g[ha(i+1, j)].push_back({ha(i, j), 1});
            }
        }
        for (int i = 1; i <= n; i ++) cin >> b[i];
        for (int i = 1; i <= K; i ++) cin >> color[i]+1;
        for (int i = 1; i <= n; i ++) {
            g[ha(i, 0)].push_back({ha(i, b[i]), 0});
            for (int j = 1; j <= K; j ++) if (color[j][b[i]] == '1') g[ha(i, j)].push_back({ha(i, 0), 0});
        }
        memset(dis, -1, sizeof(dis));
        que.push({ha(1, 0), 0});
        dis[ha(1, 0)] = 0;
        while (!que.empty()) {
            Node nd = que.top();
            que.pop();
            int u = nd.u, d = nd.dis;
            if (vis[u]) continue;
            vis[u] = true;
            if (u == ha(n, 0)) break;
            for (auto e : g[u]) {
                int v = e.v, w = e.w;
                if (dis[v] == -1 || dis[v] > d + w) {
                    dis[v] = d + w;
                    que.push({v, d+w});
                }
            }
        }
        cout << dis[ha(n, 0)] << endl;
        return 0;
    }
    
  • 相关阅读:
    hdu1754 I Hate It
    51nod 1174 1174 区间中最大的数
    51nod1305 Pairwise Sum and Divide
    51nod 1622 集合对[算法马拉松19 C]
    51nod1265 四点共面
    51nod 1244 莫比乌斯函数之和
    51nod 1240 莫比乌斯函数
    51nod 1113 矩阵快速幂
    51nod 1264 线段相交(几何)
    51nod 1412 AVL树的种类(dp)
  • 原文地址:https://www.cnblogs.com/quanjun/p/15564130.html
Copyright © 2020-2023  润新知