Submission #1230646

#TimeUsernameProblemLanguageResultExecution timeMemory
1230646biankRobot (JOI21_ho_t4)C++20
0 / 100
85 ms15548 KiB
#include <bits/stdc++.h>

using namespace std;

#define forsn(i, s, n) for (int i = int(s); i < int(n); i++)
#define forn(i, n) forsn(i, 0, n)
#define dforsn(i, s, n) for (int i = int(n) - 1; i >= int(s); i--)
#define dforn(i, n) dforsn(i, 0, n)

#define sz(x) int(x.size())
#define all(x) begin(x), end(x)

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vb = vector<bool>;
using vll = vector<ll>;
using ii = pair<int, int>;
using iii = tuple<int, int, int>;

#define fst first
#define snd second

#define pb push_back
#define eb emplace_back

const ll INF = 1e18;

struct Edge {
    int u, v, c; 
    ll p;
};

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    
    int n, m;
    cin >> n >> m;
    vector<Edge> graph(m);
    vector<vector<iii>> adj(n);
    vector<map<int, ll>> sum(n);
    for (auto &[u, v, c, p] : graph) {
        cin >> u >> v >> c >> p;
        --u, --v;
        sum[u][c] += p;
        sum[v][c] += p;
    }
    for (auto &[u, v, c, p] : graph) {
        adj[u].eb(c, v, min(p, sum[u][c] - p));
        adj[v].eb(c, u, min(p, sum[v][c] - p));
    }
    forn(u, n) {
        sort(all(adj[u]));
    }
    vector<vll> dist(n);
    forn(u, n) dist[u].assign(sz(adj[u]) + 1, INF);
    priority_queue<tuple<ll, int, int>> pq;
    auto PUSH = [&](int u, int s, ll d) {
        if (d < dist[u][s]) {
            dist[u][s] = d;
            pq.emplace(-dist[u][s], u, s);
        }
    };
    auto pos = [&](int u, iii e) {
        return int(lower_bound(all(adj[u]), e) - begin(adj[u]));
    };
    PUSH(0, sz(adj[0]), 0LL);
    while (!pq.empty()) {
        auto [d, u, s] = pq.top();
        pq.pop(); d *= -1;
        if (dist[u][s] != d) continue;
        int k = sz(adj[u]);
        if (s != k) {
            PUSH(u, k, d);
            int c = get<0>(adj[u][s]);
            bool prv = s >= 1 && get<0>(adj[u][s - 1]) == c;
            bool nxt = s + 1 < k && get<0>(adj[u][s + 1]) == c;
            if (prv && nxt) continue;
            if (prv && (s == 1 || get<0>(adj[u][s - 2]) != c)) {
                auto [c, v, p] = adj[u][s - 1];
                PUSH(v, pos(v, iii{c, u, p}), d);
            }
            if (nxt && (s + 2 == k || get<0>(adj[u][s + 2]) != c)) {
                auto [c, v, p] = adj[u][s + 1];
                PUSH(v, pos(v, iii{c, u, p}), d);
            }
        } else {
            forn(id, k) {
                auto [c, v, p] = adj[u][id];
                bool prv = id >= 1 && get<0>(adj[u][id - 1]) == c;
                bool nxt = id + 1 < k && get<0>(adj[u][id + 1]) == c;
                PUSH(v, pos(v, iii{c, u, p}), d + p * (prv || nxt));
            }
        }
    }
    if (dist[n - 1][sz(adj[n - 1])] == INF) cout << "-1\n";
    else cout << dist[n - 1][sz(adj[n - 1])] << '\n';
    
    
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...