Submission #1265174

#TimeUsernameProblemLanguageResultExecution timeMemory
1265174andyoCommuter Pass (JOI18_commuter_pass)C++20
0 / 100
270 ms33412 KiB
#include <iostream> #include <vector> #include <queue> #include <algorithm> #include <climits> using namespace std; typedef long long ll; typedef pair<ll, int> pli; const ll INF = 1e18; int main() { int n, m; cin >> n >> m; int s, t; cin >> s >> t; int u, v; cin >> u >> v; // Adjacency list to store the graph vector<vector<pair<int, ll>>> graph(n + 1); // Store all railways vector<tuple<int, int, ll>> railways(m); for (int i = 0; i < m; i++) { int a, b; ll c; cin >> a >> b >> c; // Store the railway railways[i] = {a, b, c}; // Add edges to the graph graph[a].push_back({b, c}); graph[b].push_back({a, c}); } // Dijkstra's algorithm to find shortest path from a given source auto dijkstra = [&](int source, vector<ll>& dist) { dist.assign(n + 1, INF); priority_queue<pli, vector<pli>, greater<pli>> pq; dist[source] = 0; pq.push({0, source}); while (!pq.empty()) { auto [d, u] = pq.top(); pq.pop(); if (d > dist[u]) continue; for (auto& [v, w] : graph[u]) { if (dist[u] + w < dist[v]) { dist[v] = dist[u] + w; pq.push({dist[v], v}); } } } }; // Find shortest path from S to T in the original graph vector<ll> dist_s_to_all; dijkstra(s, dist_s_to_all); ll original_cost_s_to_t = dist_s_to_all[t]; // For each valid S-T path, check the cost from U to V ll min_cost_u_to_v = INF; // Brute force through all possible paths from S to T // In a real implementation, we would optimize this further // Approach: Try all possible edges that could be part of commuter pass // For each possible set, compute the min cost from U to V // For simplicity, let's try a clever approach: // 1. Create a new graph where railways in S-T path have cost 0 // 2. Find shortest path from U to V in this new graph // Find the original shortest path from S to T vector<int> parent(n + 1, -1); vector<bool> is_on_st_path(m, false); // Re-run Dijkstra from S to T to get the path priority_queue<pli, vector<pli>, greater<pli>> pq; pq.push({0, s}); while (!pq.empty()) { auto [d, u] = pq.top(); pq.pop(); if (u == t) break; for (auto& [v, w] : graph[u]) { if (dist_s_to_all[u] + w == dist_s_to_all[v]) { parent[v] = u; pq.push({dist_s_to_all[v], v}); break; } } } // Mark edges on S-T path int curr = t; while (curr != s && parent[curr] != -1) { int prev = parent[curr]; for (int i = 0; i < m; i++) { auto [a, b, c] = railways[i]; if ((a == prev && b == curr) || (a == curr && b == prev)) { is_on_st_path[i] = true; break; } } curr = prev; } // Create a modified graph for U to V path vector<vector<pair<int, ll>>> modified_graph(n + 1); for (int i = 0; i < m; i++) { auto [a, b, c] = railways[i]; ll new_cost = is_on_st_path[i] ? 0 : c; modified_graph[a].push_back({b, new_cost}); modified_graph[b].push_back({a, new_cost}); } // Find shortest path from U to V in the modified graph vector<ll> dist_u_to_all(n + 1, INF); dist_u_to_all[u] = 0; priority_queue<pli, vector<pli>, greater<pli>> pq2; pq2.push({0, u}); while (!pq2.empty()) { auto [d, node] = pq2.top(); pq2.pop(); if (d > dist_u_to_all[node]) continue; for (auto& [next, weight] : modified_graph[node]) { if (dist_u_to_all[node] + weight < dist_u_to_all[next]) { dist_u_to_all[next] = dist_u_to_all[node] + weight; pq2.push({dist_u_to_all[next], next}); } } } cout << dist_u_to_all[v] << 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...