Submission #361247

#TimeUsernameProblemLanguageResultExecution timeMemory
361247HoneyBadgerOlympic Bus (JOI20_ho_t4)C++17
16 / 100
73 ms7708 KiB
#include <iostream> #include <iomanip> #include <cstdio> #include <vector> #include <bitset> #include <string> #include <cstring> #include <map> #include <set> #include <stack> #include <queue> #include <deque> #include <utility> #include <algorithm> #include <random> #include <cmath> #include <cassert> #include <climits> #include <ctime> #include <chrono> /* #pragma GCC optimize("Ofast") #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,sse4.1,sse4.2,popcnt,abm,mmx,avx,avx2,tune=native") */ #ifdef LOCAL #define dbg(x) cout << #x << " : " << x << endl; #else #define dbg(x) #endif #define int long long #define pb push_back #define ppb pop_back() #define mp make_pair #define fi(a, b) for (int i = a; i < b; i++) #define fj(a, b) for (int j = a; j < b; j++) #define fk(a, b) for (int k = a; k < b; k++) #define fi1(a, b) for (int i = a - 1; i >= b; i--) #define fj1(a, b) for (int j = a - 1; j >= b; j--) #define fk1(a, b) for (int k = a - 1; k >= b; k--) #define fx(x, a) for (auto& x : a) #define rep(i, a, b) for (int i = a; i < b; ++i) #define rep1(i, a, b) for (int i = a - 1; i >= b; --i) #define siz(x) (int)x.size() #define lb lower_bound #define ub upper_bound #define all(x) x.begin(), x.end() using namespace std; template<typename T1, typename T2>inline void mine(T1 &x, const T2 &y) { if (y < x) x = y; } template<typename T1, typename T2>inline void maxe(T1 &x, const T2 &y) { if (x < y) x = y; } ostream& operator << (ostream &out, const vector<int> &b) { for (auto k : b) out << k << ' '; return out; } typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef char ch; typedef string str; typedef pair<int, int> pii; typedef vector<int> vi; typedef vector<vi> vvi; typedef vector<pii> vpii; typedef vector<vpii> vvpii; typedef vector<ch> vch; typedef vector<vch> vvch; typedef vector<str> vs; const int MOD = 1000000007; const int INF = 1000000050; const long long BIG = (long long)2e18 + 50; const int MX = 200010; const double EPS = 1e-9; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); int n, m; int c[MX]; int from[MX]; int to[MX]; vi bandij(int s, int ban, const vvi &g) { vi dist(n, BIG); vch used(n, 0); dist[s] = 0; for (int i = 0; i < n - 1; ++i) { int v = -1; for (int j = 0; j < n; ++j) { if (!used[j] && (v == -1 || dist[j] < dist[v])) { v = j; } } if (dist[v] == BIG) break; fx(id, g[v]) { if (id == ban) continue; mine(dist[to[id]], dist[v] + c[id]); } used[v] = 1; } return dist; } pair<vvi, vi> dij(int s, const vvi & g) { vi dist(n, BIG); vch used(n, 0); vvpii gb(n); dist[s] = 0; for (int i = 0; i < n - 1; ++i) { int v = -1; for (int j = 0; j < n; ++j) { if (!used[j] && (v == -1 || dist[j] < dist[v])) { v = j; } } if (dist[v] == BIG) break; fx(id, g[v]) { if (dist[to[id]] > dist[v] + c[id]) { gb[to[id]].clear(); dist[to[id]] = dist[v] + c[id]; } if (dist[to[id]] == dist[v] + c[id]) gb[to[id]].pb({from[id], id}); } used[v] = 1; } vvpii gb2(n); for (int i = 0; i < n; ++i) { used[i] = 0; for (auto[x, id] : gb[i]) { gb2[x].pb({i, id}); } } swap(gb2, gb); vi ord; function<void(int)> dfs = [&](int v) { used[v] = 1; for (auto[x, id] : gb[v]) { if (!used[x]) { dfs(x); } } ord.pb(v); }; dfs(s); reverse(all(ord)); //dbg(ord); vi ways(n, 0); ways[s] = 1; fx(v, ord) { ways[v] %= MOD; for (auto[x, id] : gb[v]) { ways[x] += ways[v]; } } //dbg(ways); vi bridges; fx(v, ord) { for (auto[to, id] : gb[v]) { if (ways[to] == ways[v]) { bridges.pb(id); } } } sort(all(bridges)); vvi dists; fx(id, bridges) dists.pb(bandij(s, id, g)); dists.pb(dist); fx(x, bridges) x %= m; return mp(dists, bridges); } int d[MX]; int get(vi &bridges, int id) { auto it = lb(all(bridges), id); if (it == bridges.end() || *it != id) return bridges.size(); return it - bridges.begin(); } int32_t main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> m; vvi g(n); vvi gc(n); for (int i = 0; i < m; ++i) { cin >> from[i] >> to[i] >> c[i] >> d[i]; --from[i], --to[i]; from[i + m] = to[i]; to[i + m] = from[i]; c[i + m] = c[i]; g[from[i]].pb(i); gc[from[i + m]].pb(i + m); } const int s = 0; const int t = n - 1; auto[dsv, bsv] = dij(s, g); auto[dvs, bvs] = dij(s, gc); auto[dtv, btv] = dij(t, g); auto[dvt, bvt] = dij(t, gc); /*dbg(bsv); fx(di, dsv) { dbg(di); } dbg(bvs); fx(di, dvs) { dbg(di); } dbg(btv); fx(di, dtv) { dbg(di); } dbg(bvt); fx(di, dvt) { dbg(di); } dbg(btv);*/ int ans = dsv.back()[t] + dtv.back()[s]; for (int id = 0; id < m; ++id) { //#warning ALARM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //if (id != 3) continue; int u = from[id]; int v = to[id]; int bid = get(bsv, id); int st = dsv[bid][t]; int sv = dsv[bid][v]; bid = get(bvs, id); int us = dvs[bid][u]; bid = get(btv, id); //dbg(bid); int ts = dtv[bid][s]; int tv = dtv[bid][v]; bid = get(bvt, id); int ut = dvt[bid][u]; int cur = d[id]; cur += min(st, sv + c[id] + ut); cur += min(ts, tv + c[id] + us); mine(ans, cur); /*dbg(id); dbg(st); dbg(sv); dbg(us); dbg(ts); dbg(tv); dbg(ut); dbg(cur);*/ } cout << (ans >= BIG ? -1 : ans) << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...