제출 #1185148

#제출 시각아이디문제언어결과실행 시간메모리
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...