1 条题解

  • 0
    @ 2024-11-19 18:04:45

    最短路。

    可以建立 (09)(0-9) 1010 个超级源点,红绿灯编号有什么数字就建立有向边指向对应源点边权如题,再建立有向边从源点指向该红绿灯边权为 00。正常跑最短路,最后选出一家早餐店即可。

    #include <bits/stdc++.h>
    
    using i64 = long long;
    using u32 = unsigned;
    using u64 = unsigned long long;
    
    void solve() {
        int n;
        std::cin >> n;
    
        std::vector<std::vector<std::pair<int, int>>> e(n + 12);
        for (int i = 0; i <= n; ++i) {
            int w;
            std::cin >> w;
            e[i].emplace_back(i + 1, w);
            e[i + 1].emplace_back(i, w);
        }
    
        for (int i = 0; i < n; ++i) {
            int u;
            std::cin >> u;
    
            while (u) {
                int t = u % 10;
                e[i + 1].emplace_back(n + 2 + t, t);
                e[n + 2 + t].emplace_back(i + 1, 0);
                u /= 10;
            }
        }
    
        std::vector<int> a(n + 1);
        for (int i = 1; i <= n; ++i) {
            std::cin >> a[i];
        }
    
        auto dijkstra = [&](int s) -> std::vector<i64> {
            std::vector<i64> dis(n + 12, 1E18);
            std::vector<int> vis(n + 12);
            std::priority_queue<std::pair<i64, int>, std::vector<std::pair<i64, int>>, std::greater<>> pq;
            dis[s] = 0;
            pq.emplace(0, s);
            while (!pq.empty()) {
                auto [_, u] = pq.top();
                pq.pop();
    
                if (vis[u]) {
                    continue;
                }
                vis[u] = 1;
    
                for (auto [v, w] : e[u]) {
                    if (dis[v] > _ + w) {
                        dis[v] = _ + w;
                        pq.emplace(dis[v], v);
                    }
                }
            }
            return dis;
        };
    
        auto dis1 = dijkstra(0), dis2 = dijkstra(n + 1);
        i64 dis = 2E18, score = 0;
        for (int i = 1; i <= n; ++i) {
            i64 t = dis1[i] + dis2[i];
            if (t < dis) {
                dis = t;
                score = a[i];
            } else if (t == dis && a[i] > score) {
                score = a[i];
            }
        }
    
        std::cout << dis << " " << score << "\n";
    }
    
    int main() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
    
        int t;
        std::cin >> t;
    
        while (t--) {
            solve();
        }
    
        return 0;
    }
    
    • 1

    信息

    ID
    143
    时间
    3000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    4
    已通过
    3
    上传者