Submission #1185148

#TimeUsernameProblemLanguageResultExecution timeMemory
1185148witek_cppOlympic Bus (JOI20_ho_t4)C++20
0 / 100
17 ms1864 KiB
#include <iostream> #include <vector> #include <algorithm> #include <limits> using namespace std; typedef long long ll; const ll INF = 1LL << 60; // wystarczająco duża wartość (ok. 1e18) int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int N, M; cin >> N >> M; // Utworz macierz odległości – indeksujemy miasta od 1 do N. vector<vector<ll>> d(N+1, vector<ll>(N+1, INF)); for (int i = 1; i <= N; i++){ d[i][i] = 0; } // Zachowujemy dane o liniach autobusowych: // każda linia: U -> V, fare = C, cost inversion = D. struct Edge { int U, V; ll C, D; }; vector<Edge> edges(M); // Wczytanie wejścia – uaktualniamy także d dla krawędzi bezpośrednich. for (int i = 0; i < M; i++){ int U, V; ll C, D; cin >> U >> V >> C >> D; edges[i] = {U, V, C, D}; // Może być wiele krawędzi między parą w tym samym kierunku, więc bierzemy minimum. d[U][V] = min(d[U][V], C); } // Obliczamy macierz najkrótszych ścieżek metodą Floyda–Warshalla for (int k = 1; k <= N; k++){ for (int i = 1; i <= N; i++){ if(d[i][k] == INF) continue; for (int j = 1; j <= N; j++){ if(d[k][j] == INF) continue; d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } // Najpierw rozważamy sytuację bez odwracania żadnej linii. ll ans = INF; if(d[1][N] != INF && d[N][1] != INF){ ans = d[1][N] + d[N][1]; } // Następnie rozważamy odwracanie każdej krawędzi for (int i = 0; i < M; i++){ int U = edges[i].U; int V = edges[i].V; ll C = edges[i].C; ll D = edges[i].D; // Możemy wykorzystać odwróconą krawędź na drodze 1->N albo na drodze N->1. // Wariant 1: odwrócona krawędź użyta na drodze z 1 do N: droga = // 1 -> V (oryginalnie), + odwrócona krawędź V->U (koszt C), + U -> N (oryginalnie) // oraz dodatkowo powrót N -> 1 (oryginalnie) if(d[1][V] != INF && d[U][N] != INF && d[N][1] != INF){ ll cost = d[1][V] + C + d[U][N] + d[N][1] + D; ans = min(ans, cost); } // Wariant 2: odwrócona krawędź użyta na drodze powrotnej z N do 1: droga = // Powrót: N -> V (oryginalnie), + odwrócona krawędź V->U (koszt C), + U -> 1 (oryginalnie) // oraz dodatkowo droga 1 -> N (oryginalnie) if(d[1][N] != INF && d[N][V] != INF && d[U][1] != INF){ ll cost = d[1][N] + d[N][V] + C + d[U][1] + D; ans = min(ans, cost); } } if(ans >= INF/2) cout << -1 << "\n"; else cout << ans << "\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...