zoukankan      html  css  js  c++  java
  • 洛谷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;
    }
    
  • 相关阅读:
    oracle 数据库关闭的的几种方式总结
    oracle热备份
    oracle 的 startup,startup mount,startup nomount之间的区别
    Oracle数据导入导出imp/exp命令总结
    oracle模糊查询效率可这样提高
    流程控制
    常量
    java序列化
    JVM锁说明
    go变量和数据类型
  • 原文地址:https://www.cnblogs.com/quanjun/p/15564130.html
Copyright © 2011-2022 走看看