제출 #1286746

#제출 시각아이디문제언어결과실행 시간메모리
1286746harryleeeCommuter Pass (JOI18_commuter_pass)C++20
100 / 100
386 ms22296 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; const ll INF = (ll)4e18; struct Edge { int u, v; int w; }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; int S, T, U, V; if (!(cin >> n >> m >> S >> T >> U >> V)) return 0; vector<Edge> edges(m+1); vector<vector<pair<int,int>>> adj(n+1); for (int i = 1; i <= m; ++i) { int a, b, c; cin >> a >> b >> c; edges[i] = {a,b,c}; adj[a].push_back({b, i}); adj[b].push_back({a, i}); } auto dijkstra_from = [&](int src) { vector<ll> dist(n+1, INF); priority_queue<pair<ll,int>, vector<pair<ll,int>>, greater<pair<ll,int>>> pq; dist[src] = 0; pq.push({0, src}); while (!pq.empty()) { auto [d, u] = pq.top(); pq.pop(); if (d != dist[u]) continue; for (auto [v, eid] : adj[u]) { int w = edges[eid].w; if (dist[v] > d + w) { dist[v] = d + w; pq.push({dist[v], v}); } } } return dist; }; vector<ll> distS = dijkstra_from(S); vector<ll> distT = dijkstra_from(T); vector<ll> distU = dijkstra_from(U); vector<ll> distV = dijkstra_from(V); // Mark edges that lie on some shortest path from S to T and build directed DAG (forward along distS) vector<vector<int>> dag(n+1); for (int i = 1; i <= m; ++i) { int u = edges[i].u, v = edges[i].v, w = edges[i].w; // if u->v is forward on some shortest S->T path if (distS[u] + w + distT[v] == distS[T] && distS[u] + w == distS[v]) { dag[u].push_back(v); } if (distS[v] + w + distT[u] == distS[T] && distS[v] + w == distS[u]) { dag[v].push_back(u); } } // sort vertices by distS (increasing). Edges in dag go from smaller distS to larger distS vector<int> ord(n); for (int i = 0; i < n; ++i) ord[i] = i+1; sort(ord.begin(), ord.end(), [&](int a, int b){ return distS[a] < distS[b]; }); auto solve_with_shop = [&](const vector<ll>& distShop) { // DP: best[u] = minimal value of min(distShop[x]) along any path from S to u in DAG vector<ll> best(n+1, INF); best[S] = distShop[S]; ll res = INF; for (int u : ord) { if (best[u] == INF) continue; // unreachable in DAG from S // candidate answer: choose route such that up to u we use zero cost, then pay distV[u] res = min(res, best[u] + distV[u]); for (int v : dag[u]) { ll cand = min(best[u], distShop[v]); if (cand < best[v]) best[v] = cand; } } return res; }; // Two possibilities: choose route and pay remaining either using shop U->V or swap shops? // The original logic runs solve starting from shop1 and then swap shop1/shop2; we mimic that: vector<ll> distShop1 = distU; vector<ll> distShop2 = distV; // first candidate: no zero-route used (just pay direct U->V) ll answer = min(distShop1[V], distShop2[U]); // direct without any road chosen (both directions considered) // try using DAG + shop1 as "free" source along route ll cand1 = solve_with_shop(distShop1); // now swap roles: we want shop2 as free-source and distU used as distV vector in lambda, so we need to rebuild lambda using other distV // simplest: swap global distV (used in lambda). We'll implement solve_with_shop2 to use distU as second distance: // For clarity, duplicate function to use appropriate distal second term. auto solve_with_shop_and_other = [&](const vector<ll>& distShop, const vector<ll>& otherDist) { vector<ll> best(n+1, INF); best[S] = distShop[S]; ll res2 = INF; for (int u : ord) { if (best[u] == INF) continue; res2 = min(res2, best[u] + otherDist[u]); for (int v : dag[u]) { ll cand = min(best[u], distShop[v]); if (cand < best[v]) best[v] = cand; } } return res2; }; ll candA = solve_with_shop_and_other(distShop1, distV); // original: best + dis_shop2[u] where shop2==V ll candB = solve_with_shop_and_other(distShop2, distU); // swapped roles answer = min(answer, min({candA, candB})); if (answer >= INF/4) answer = -1; // if unreachable, depends on problem statement (but keep existing) cout << answer << "\n"; 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...