#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |