제출 #1364895

#제출 시각아이디문제언어결과실행 시간메모리
1364895khongbietdatgiRobot (JOI21_ho_t4)C++20
100 / 100
538 ms79368 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
const ll INF = (1LL << 62);

struct Edge {
    int to;
    ll p;
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;

    vector<map<int, vector<Edge>>> g(n + 1);
    vector<map<int, ll>> sum(n + 1);

    for (int i = 1; i <= m; ++i) {
        int u, v, c;
        ll p;
        cin >> u >> v >> c >> p;
        g[u][c].push_back({v, p});
        g[v][c].push_back({u, p});
        sum[u][c] += p;
        sum[v][c] += p;
    }

    vector<ll> dp(n + 1, INF);
    vector<map<int, ll>> dp2(n + 1);

    using State = tuple<ll, int, int>; // dist, node, color (0 = normal)
    priority_queue<State, vector<State>, greater<State>> pq;

    dp[1] = 0;
    pq.emplace(0, 1, 0);

    while (!pq.empty()) {
        auto [dist, u, c] = pq.top();
        pq.pop();

        if (c == 0) {
            if (dist != dp[u]) continue;

            for (auto &kv : g[u]) {
                int color = kv.first;
                ll total = sum[u][color];

                for (auto &e : kv.second) {
                    // Case 1: recolor the other same-colored roads at u
                    ll nd1 = dist + total - e.p;
                    if (nd1 < dp[e.to]) {
                        dp[e.to] = nd1;
                        pq.emplace(nd1, e.to, 0);
                    }

                    // Case 2: recolor this road directly
                    ll nd2 = dist + e.p;
                    if (nd2 < dp[e.to]) {
                        dp[e.to] = nd2;
                        pq.emplace(nd2, e.to, 0);
                    }

                    // Case 3: keep a pending state for this color
                    auto it = dp2[e.to].find(color);
                    if (it == dp2[e.to].end() || dist < it->second) {
                        dp2[e.to][color] = dist;
                        pq.emplace(dist, e.to, color);
                    }
                }
            }
        } else {
            auto it = dp2[u].find(c);
            if (it == dp2[u].end() || dist != it->second) continue;

            auto git = g[u].find(c);
            if (git == g[u].end()) continue;

            ll total = sum[u][c];
            for (auto &e : git->second) {
                ll nd = dist + total - e.p;
                if (nd < dp[e.to]) {
                    dp[e.to] = nd;
                    pq.emplace(nd, e.to, 0);
                }
            }
        }
    }

    if (dp[n] >= INF / 2) cout << -1;
    else cout << dp[n];
    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…