Submission #1265169

#TimeUsernameProblemLanguageResultExecution timeMemory
1265169andyoCommuter Pass (JOI18_commuter_pass)C++20
16 / 100
240 ms19324 KiB
#include <iostream> #include <vector> #include <queue> #include <algorithm> using namespace std; const long long INF = 1e18; struct Edge { int to; long long cost; }; vector<long long> dijkstra(int start, const vector<vector<Edge>>& graph) { int n = graph.size(); vector<long long> dist(n, INF); priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq; dist[start] = 0; pq.push({0, start}); while (!pq.empty()) { long long d = pq.top().first; int u = pq.top().second; pq.pop(); if (d > dist[u]) continue; for (const Edge& e : graph[u]) { if (dist[u] + e.cost < dist[e.to]) { dist[e.to] = dist[u] + e.cost; pq.push({dist[e.to], e.to}); } } } return dist; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int N, M; cin >> N >> M; int S, T, U, V; cin >> S >> T >> U >> V; S--; T--; U--; V--; // Convert to 0-indexed vector<vector<Edge>> graph(N); for (int i = 0; i < M; i++) { int a, b; long long c; cin >> a >> b >> c; a--; b--; // Convert to 0-indexed graph[a].push_back({b, c}); graph[b].push_back({a, c}); } // Calculate shortest distances from all key points vector<long long> distS = dijkstra(S, graph); vector<long long> distT = dijkstra(T, graph); vector<long long> distU = dijkstra(U, graph); vector<long long> distV = dijkstra(V, graph); long long shortestST = distS[T]; // Initialize result with direct path from U to V (no commuter pass used) long long result = distU[V]; // The key insight: The commuter pass covers some shortest path from S to T. // We can use this path for free in our journey from U to V. // We need to consider all possible ways to utilize this free path: // Strategy 1: Go U -> S -> T -> V (use entire S->T path) result = min(result, distU[S] + distT[V]); // Strategy 2: Go U -> T -> S -> V (use entire T->S path) result = min(result, distU[T] + distS[V]); // Strategy 3: Use intermediate points on the shortest S->T path // For any point X that lies on some shortest path from S to T: // - Distance from S to X plus distance from X to T equals shortestST // - We can go U -> X -> V, using either S->X or X->T portion for free for (int x = 0; x < N; x++) { // Check if x lies on some shortest path from S to T if (distS[x] + distT[x] == shortestST) { // Case 3a: U -> X -> V, utilizing the fact that we can reach X from S for free // or reach T from X for free (whichever is better) result = min(result, distU[x] + distV[x]); // Case 3b: U -> S -> X -> V (S->X is free) result = min(result, distU[S] + distV[x]); // Case 3c: U -> X -> T -> V (X->T is free) result = min(result, distU[x] + distV[T]); } } cout << result << endl; 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...