Submission #1308125

#TimeUsernameProblemLanguageResultExecution timeMemory
1308125dimitris71Commuter Pass (JOI18_commuter_pass)C++20
100 / 100
180 ms23064 KiB
#include <iostream> #include <vector> #include <queue> #include <algorithm> using namespace std; typedef long long ll; const ll INF = 1e16; // Προσοχή στο INF για να μην έχουμε overflow struct Edge { int to; ll weight; }; struct Node { int id; ll dist; bool operator>(const Node& other) const { return dist > other.dist; } }; int N, M; vector<Edge> adj[100005]; void dijkstra(int start, vector<ll>& dists) { dists.assign(N + 1, INF); priority_queue<Node, vector<Node>, greater<Node>> pq; dists[start] = 0; pq.push({start, 0}); while (!pq.empty()) { Node curr = pq.top(); pq.pop(); if (curr.dist > dists[curr.id]) continue; for (auto& e : adj[curr.id]) { if (dists[curr.id] + e.weight < dists[e.to]) { dists[e.to] = dists[curr.id] + e.weight; pq.push({e.to, dists[e.to]}); } } } } int main() { ios::sync_with_stdio(false); cin.tie(NULL); int s, t, a, b; if (!(cin >> N >> M)) return 0; cin >> s >> t >> a >> b; for (int i = 0; i < M; i++) { int u, v; ll c; cin >> u >> v >> c; adj[u].push_back({v, c}); adj[v].push_back({u, c}); } // 4 Dijkstra για να ξέρουμε αποστάσεις από όλα τα κρίσιμα σημεία vector<ll> dS, dT, dA, dB; dijkstra(s, dS); dijkstra(t, dT); dijkstra(a, dA); dijkstra(b, dB); ll minST = dS[t]; ll result = dA[b]; // Αρχική τιμή: το απλό συντομότερο a-b // Δημιουργούμε ένα DAG με τις ακμές που ανήκουν σε συντομότερα s-t μονοπάτια vector<int> dag_adj[100005]; vector<int> in_degree(N + 1, 0); for (int u = 1; u <= N; u++) { for (auto& e : adj[u]) { if (dS[u] + e.weight + dT[e.to] == minST) { dag_adj[u].push_back(e.to); in_degree[e.to]++; } } } // DP πάνω στο DAG για να βρούμε το μέγιστο "κέρδος" (δωρεάν διαδρομή) // d_overlap[u]: η ελάχιστη απόσταση από το 'a' στο 'u' αν χρησιμοποιήσουμε // ένα τμήμα του s-t μονοπατιού που καταλήγει στο u. vector<ll> dp_a(N + 1, INF), dp_b(N + 1, INF); // Τοπική ταξινόμηση (Topological Sort) για το DAG queue<int> q; for (int i = 1; i <= N; i++) if (in_degree[i] == 0) q.push(i); while (!q.empty()) { int u = q.front(); q.pop(); // Η απόσταση στο u μπορεί να είναι η απευθείας από το 'a' // ή να συνεχίζει από έναν προκάτοχο στο DAG με κόστος 0 dp_a[u] = min(dp_a[u], dA[u]); dp_b[u] = min(dp_b[u], dB[u]); result = min(result, dp_a[u] + dB[u]); result = min(result, dp_b[u] + dA[u]); for (int v : dag_adj[u]) { dp_a[v] = min(dp_a[v], dp_a[u]); dp_b[v] = min(dp_b[v], dp_b[u]); if (--in_degree[v] == 0) q.push(v); } } 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...