Submission #1297555

#TimeUsernameProblemLanguageResultExecution timeMemory
1297555fairkrashOlympic Bus (JOI20_ho_t4)C++20
100 / 100
346 ms6516 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; } vector<vector<ll>> pp; vector<vector<ll>> dd; vector<ll> qq; vector<ll> used; vector<ll> color; ll cv = 0; void dfs(ll v) { used[v] = 1; for (auto to: pp[v]) { if (used[to] == 0) { dfs(to); } } qq.push_back(v); } void bfs(ll v) { used[v] = 1; color[v] = cv; for (auto to: dd[v]) { if (used[to] == 0) { bfs(to); } } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin >> n >> m; g.assign(n, {}); pp.assign(n, {}); dd.assign(n, {}); used.assign(n, 0); color.assign(n, 0); rg.assign(n, {}); vector<node> r(m); vector<pair<ll, ll>> bad; for (ll i = 0; i < m; i++) { ll a, b, c, d; cin >> a >> b >> c >> d; a--; b--; if (c == 0) { pp[a].push_back(b); dd[b].push_back(a); } r[i] = {a, b, c, d}; } for (ll i = 0; i < n; i++) { if (used[i] == 0) { dfs(i); } } std::reverse(qq.begin(), qq.end()); used.assign(n, 0); for (ll i = 0; i < qq.size(); i++) { if (used[qq[i]] == 0) { bfs(qq[i]); cv++; } } for (ll j = 0; j < m; j++) { r[j].a = color[r[j].a]; r[j].b = color[r[j].b]; ll a = r[j].a, b = r[j].b, c = r[j].c, d = r[j].d; if (r[j].a == r[j].b)continue; g[a].push_back({b, c, d}); rg[b].push_back({a, c, d}); } vector<pair<ll, ll>> dist_l_a = dxs(color[0]); vector<pair<ll, ll>> dist_r_a = dxs_r(color[0]); vector<pair<ll, ll>> dist_l_b = dxs(color[n - 1]); vector<pair<ll, ll>> dist_r_b = dxs_r(color[n - 1]); ll answer = dist_l_a[color[n - 1]].first + dist_l_b[color[0]].first; for (ll i = 0; i < m; i++) { if (r[i].a == r[i].b)continue; 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); } cnt = dist_l_a[r[i].b].first + r[i].d + r[i].c + dist_r_b[r[i].a].first + dist_l_b[color[0]].first; if (dist_l_b[color[0]].second != dist_l_b[r[i].a].second * dist_r_a[r[i].b].second) { answer = min(answer, cnt); } cnt = r[i].d + r[i].c + dist_l_b[r[i].b].first + dist_r_a[r[i].a].first + dist_l_a[color[n - 1]].first; if (dist_l_a[color[n - 1]].second != dist_l_a[r[i].a].second * dist_r_b[r[i].b].second) { answer = min(answer, cnt); } } for (ll i = 0; i < m; i++) { if (r[i].a == r[i].b)continue; 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 { if (answer > cnt) { bad.push_back({cnt, 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[color[0]].first; if (dist_l_b[color[0]].second != dist_l_b[r[i].a].second * dist_r_a[r[i].b].second) { answer = min(answer, cnt); } else { if (answer > cnt) { bad.push_back({cnt, 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[color[n - 1]].first; if (dist_l_a[color[n - 1]].second != dist_l_a[r[i].a].second * dist_r_b[r[i].b].second) { answer = min(answer, cnt); } else { if (answer > cnt) { bad.push_back({cnt, 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++) { if (answer <= bad[i].first) { break; } g.assign(n, {}); for (ll j = 0; j < m; j++) { if (r[j].a == r[j].b)continue; ll a = r[j].a, b = r[j].b, c = r[j].c, d = r[j].d; if (j == bad[i].second) { g[b].push_back({a, c, d}); continue; } g[a].push_back({b, c, d}); } vector<pair<ll, ll>> v1 = dxs(color[0]), v2 = dxs(color[n - 1]); answer = min(answer, v1[color[n - 1]].first + v2[color[0]].first + r[bad[i].second].d); } 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...