Submission #1296795

#TimeUsernameProblemLanguageResultExecution timeMemory
1296795fairkrashOlympic Bus (JOI20_ho_t4)C++20
0 / 100
1096 ms6800 KiB
#include <bits/stdc++.h>

using namespace std;
using ll = long long;
ll INF = 1e18;
ll MOD = 1e9 + 7;

struct zxc {
    ll v;
    ll cost;
    ll revers;
};

struct node {
    ll a, b, c, d;
};

ll n, m;
vector<vector<zxc>> g, rg;

vector<pair<ll, ll>> dxs(ll v) {
    vector<pair<ll, ll>> dist(n, {INF, 0});
    set<pair<ll, ll>> st;
    dist[v].first = 0;
    dist[v].second = 1;
    st.insert({dist[v].first, v});
    while (!st.empty()) {
        ll u = st.begin()->second;
        st.erase(st.begin());
        for (auto to: g[u]) {
            ll cnt = to.cost + dist[u].first;
            if (dist[to.v].first > cnt) {
                st.erase({dist[to.v].first, to.v});
                dist[to.v].first = cnt;
                dist[to.v].second = dist[u].second;
                st.insert({dist[to.v].first, to.v});
            } else {
                if (dist[to.v].first == cnt) {
                    dist[to.v].second += dist[u].second;
                }
            }
        }
    }
    return dist;
}

vector<pair<ll, ll>> dxs_r(ll v) {
    vector<pair<ll, ll>> dist(n, {INF, 0});
    set<pair<ll, ll>> st;
    dist[v].first = 0;
    dist[v].second = 1;
    st.insert({dist[v].first, v});
    while (!st.empty()) {
        ll u = st.begin()->second;
        st.erase(st.begin());
        for (auto to: rg[u]) {
            ll cnt = to.cost + dist[u].first;
            if (dist[to.v].first > cnt) {
                st.erase({dist[to.v].first, to.v});
                dist[to.v].first = cnt;
                dist[to.v].second = dist[u].second;
                st.insert({dist[to.v].first, to.v});
            } else {
                if (dist[to.v].first == cnt) {
                    dist[to.v].second += dist[u].second;
                }
            }
        }
    }
    return dist;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cin >> n >> m;
    g.assign(n, {});
    rg.assign(n, {});
    vector<node> r(m);
    vector<ll> bad;
    for (ll i = 0; i < m; i++) {
        ll a, b, c, d;
        cin >> a >> b >> c >> d;
        a--;
        b--;
        r[i] = {a, b, c, d};
        g[a].push_back({b, c, d});
        rg[b].push_back({a, c, d});
    }
    vector<pair<ll, ll>> dist_l_a = dxs(0);
    vector<pair<ll, ll>> dist_r_a = dxs_r(0);
    vector<pair<ll, ll>> dist_l_b = dxs(n - 1);
    vector<pair<ll, ll>> dist_r_b = dxs_r(n - 1);
    ll answer = dist_l_a[n - 1].first + dist_l_b[0].first;
    for (ll i = 0; i < m; i++) {
        ll cnt = dist_l_a[r[i].b].first + r[i].d + r[i].c + dist_r_b[r[i].a].first + r[i].c + dist_l_b[r[i].b].first +
                 dist_r_a[r[i].a].first;
        if (dist_l_b[r[i].b].second != dist_l_b[r[i].a].second && dist_l_a[r[i].b].second != dist_l_a[r[i].a].second) {
            answer = min(answer, cnt);
        } else {
            bad.push_back(i);
        }
        cnt = dist_l_a[r[i].b].first + r[i].d + r[i].c + dist_r_b[r[i].a].first + dist_l_b[0].first;
        if (dist_l_b[0].second != dist_l_b[r[i].a].second * dist_r_a[r[i].b].second) {
            answer = min(answer, cnt);
        } else {
            bad.push_back(i);
        }
        cnt = r[i].d + r[i].c + dist_l_b[r[i].b].first +
              dist_r_a[r[i].a].first + dist_l_a[n - 1].first;
        if (dist_l_a[n - 1].second != dist_l_a[r[i].a].second * dist_r_b[r[i].b].second) {
            answer = min(answer, cnt);
        } else {
            bad.push_back(i);
        }
    }
    if (!bad.empty()) {
        std::sort(bad.begin(), bad.end());
        bad.resize(std::unique(bad.begin(), bad.end()) - bad.begin());
    }
    for (ll i = 0; i < bad.size(); i++) {
        g.assign(n, {});
        for (ll j = 0; j < m; j++) {
            ll a = r[j].a, b = r[j].b, c = r[j].c, d = r[j].d;
            if (j == bad[i]) {
                g[b].push_back({a, c, d});
                continue;
            }
            g[a].push_back({b, c, d});
        }
        vector<pair<ll, ll>> v1 = dxs(0), v2 = dxs(n - 1);
        answer = min(answer, v1[n - 1].first + v2[0].first);
    }
    if (answer >= INF) {
        cout << -1 << endl;
        return 0;
    }
    cout << answer;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...