Submission #1193768

#TimeUsernameProblemLanguageResultExecution timeMemory
1193768vux2codeCommuter Pass (JOI18_commuter_pass)C++20
0 / 100
425 ms206332 KiB
// Src : Vux2Code /* Note : */ #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef pair<ll, ll> pll; typedef pair<ll, pll> lll; #define fi first #define se second #define pusb push_back #define popb pop_back #define pusf push_front #define popf pop_front #define vec3d vector<vector<vector<ll>>> #define vec2d vector<vector<ll>> #define vec1d vector<ll> vec3d set3 (ll x, ll y, ll z, ll val = 0) {return vec3d (x, vec2d (y, vec1d (z, val)));} vec2d set2 (ll x, ll y, ll val = 0) {return vec2d (x, vec1d (y, val));} // debug (+20) #define debug(...) debug_impl(#__VA_ARGS__, __VA_ARGS__) template<typename... Args> void debug_impl(const char* names, Args&&... args) { vector<string> _names; { istringstream ss(names); string token; while (getline(ss, token, ',')) { auto l = token.find_first_not_of(" \t"); auto r = token.find_last_not_of(" \t"); if (l == string::npos) _names.push_back(""); else _names.push_back(token.substr(l, r - l + 1)); } } cerr << "("; size_t _i = 0; int _dummy[] = { 0, ((cerr << _names[_i] << " : " << args << (++_i < _names.size() ? ", " : "")), 0)... }; (void)_dummy; cerr << ")" << endl; } // handy for loops #define forinc(i, a, b) for (ll i = (a); i <= (b); ++i) #define fordec(i, a, b) for (ll i = (a); i >= (b); --i) #define foreach(i, j) for (ll i : (j)) #define all(a) (a).begin (), (a). end () #define uni(a) (a).erase(unique((a).begin(), (a). end ()), (a). end ()) const ll maxN = 1e6 + 5, maxLog = 20, inf64 = 1e18, inf32 = 1e9, mod = 1e9 + 7; void maxi(ll &x, ll y) { x = max(x, y); } void mini(ll &x, ll y) { x = min(x, y); } ll t = 1; ll n, m, d1 [maxN], d2 [maxN] [3]; pll s1, s2; vector <pll> adj [maxN]; vec1d trace [maxN]; priority_queue <pll, vector <pll>, greater <pll>> q; priority_queue <lll, vector <lll>, greater <lll>> q3; queue <ll> fq; set <ll> mp1 [maxN], mp2 [maxN]; bool vst [maxN]; bool fin (set <ll> &x, ll y) { return (x.find(y) == x.end()); } void up (ll x, ll y, ll v) { if (d2[x][y] > v) { d2[x][y] = v; q3.push({d2[x][y], {x, y}}); } } void solve() { cin >> n >> m >> s1.fi >> s1.se >> s2.fi >> s2.se; forinc(i, 1, m) { ll a, b, c; cin >> a >> b >> c; adj[a].pusb({b, c}); adj[b].pusb({a, c}); } // 1. Dijkstra từ s1.fi, giữ trace các cha memset(d1, 0x3f, sizeof d1); d1[s1.fi] = 0; q.push({0, s1.fi}); while (!q.empty()) { auto [dist, u] = q.top(); q.pop(); if (dist != d1[u]) continue; for (auto &e : adj[u]) { ll v = e.fi, w = e.se; if (d1[v] > dist + w) { d1[v] = dist + w; trace[v].clear(); trace[v].pusb(u); q.push({d1[v], v}); } else if (d1[v] == dist + w) { trace[v].pusb(u); } } } // 2. Xây mp1/mp2 cho mọi cạnh trên DAG (cung trên đường ngắn nhất) // rồi BFS để tìm các đỉnh thực sự nằm trên DAG forinc(i, 1, n) { for (ll p : trace[i]) { mp1[p].insert(i); mp2[i].insert(p); } } memset(vst, 0, sizeof vst); fq.push(s1.se); vst[s1.se] = true; while (!fq.empty()) { ll u = fq.front(); fq.pop(); for (ll p : trace[u]) { // ghi nhận cung nếu chưa có, nhưng BFS qua đỉnh mỗi đỉnh một lần if (!vst[p]) { vst[p] = true; fq.push(p); } } } ll ans = inf64; // 3. Dijkstra đa trạng thái từ s2.fi memset(d2, 0x3f, sizeof d2); d2[s2.fi][0] = 0; q3.push({0, {s2.fi, 0}}); while (!q3.empty()) { auto [val, st] = q3.top(); q3.pop(); ll u = st.fi, sta = st.se; if (val != d2[u][sta]) continue; for (auto &e : adj[u]) { ll v = e.fi, w = e.se; bool isDAG = mp1[u].count(v) > 0; if (isDAG) { // miễn phí nếu đang state 0 hoặc 1 if (sta == 0 || sta == 1) up(v, 1, val); else /* sta==2 */ up(v, 2, val + w); } else { ll cost = val + w; if (sta == 0) up(v, 0, cost); else up(v, 2, cost); } } } mini(ans, d2[s2.se][0]); mini(ans, d2[s2.se][1]); mini(ans, d2[s2.se][2]); // 4. Lặp lại với hoán đổi s1.se <-> s1.fi (đảo chiều đường ngắn nhất) memset(d2, 0x3f, sizeof d2); d2[s2.fi][0] = 0; q3.push({0, {s2.fi, 0}}); while (!q3.empty()) { auto [val, st] = q3.top(); q3.pop(); ll u = st.fi, sta = st.se; if (val != d2[u][sta]) continue; for (auto &e : adj[u]) { ll v = e.fi, w = e.se; bool isDAG = mp2[u].count(v) > 0; if (isDAG) { if (sta == 0 || sta == 1) up(v, 1, val); else up(v, 2, val + w); } else { ll cost = val + w; if (sta == 0) up(v, 0, cost); else up(v, 2, cost); } } } mini(ans, d2[s2.se][0]); mini(ans, d2[s2.se][1]); mini(ans, d2[s2.se][2]); // So sánh với không dùng vé // ... nếu cần, so sánh với khoảng cách trực tiếp cout << ans; } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); while (t--) solve(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...