Submission #1271657

#TimeUsernameProblemLanguageResultExecution timeMemory
1271657cokalhadoOlympic Bus (JOI20_ho_t4)C++20
16 / 100
58 ms4680 KiB
// https://oj.uz/problem/view/JOI20_ho_t4
#include<bits/stdc++.h>
using namespace std;

#define int long long

const int maxn = 210;
const int maxm = 5e4+10;
const int inf = 1e18;
const int comp = 1e17;
int N, M;
vector<pair<int, int>> g[maxn][2];
tuple<int, int, int, int> ar[maxm];
int dist[maxn];
bool proc[maxn];
int ans = inf;
int P[maxn][4];

void dijkstra(int A, bool b)
{
    for(int i = 1; i <= N; i++)
    {
        dist[i] = 0;
        proc[i] = 0;
    }
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    pq.push({1, A});
    dist[A] = 1;
    while(!pq.empty())
    {
        int x = pq.top().second;
        pq.pop();
        if(proc[x]) continue;
        proc[x] = 1;
        for(auto[v, w] : g[x][b])
        {
            if(dist[v] == 0 || dist[x]+w < dist[v])
            {
                dist[v] = dist[x]+w;
                pq.push({dist[v], v});
            }
        }
    }
}

int32_t main()
{
    cin >> N >> M;
    for(int i = 1; i <= M; i++)
    {
        int u, v, c, d;
        cin >> u >> v >> c >> d;
        ar[i] = make_tuple(u, v, c, d);
        g[u][0].push_back({v, c});
        g[v][1].push_back({u, c});
    }

    if(M <= 1000)
    {
        for(int i = 0; i <= M; i++)
        {
            int D = 0;
            if(i != 0)
            {
                auto[u, v, c, d] = ar[i];
                for(auto it = g[u][0].begin(); it != g[u][0].end(); it++)
                {
                    if(it->first == v && it->second == c)
                    {
                        g[u][0].erase(it);
                        break;
                    }
                }
                g[v][0].push_back({u, c});
                D = d;
            }
            dijkstra(1, 0);
            int p1 = dist[N]-1;
            dijkstra(N, 0);
            int p2 = dist[1]-1;
            if(p1 != -1 && p2 != -1) ans = min(ans, p1+p2+D);
            if(i != 0)
            {
                auto[u, v, c, d] = ar[i];
                for(auto it = g[v][0].begin(); it != g[v][0].end(); it++)
                {
                    if(it->first == u && it->second == c)
                    {
                        g[v][0].erase(it);
                        break;
                    }
                }
                g[u][0].push_back({v, c});
            }
        }
        cout << (ans > comp ? -1 : ans);
        return 0;
    }

    dijkstra(1, 0);
    for(int i = 1; i <= N; i++)
    {
        P[i][0] = dist[i]-1;
        if(P[i][0] == -1) P[i][0] = inf;
    }
    dijkstra(N, 1);
    for(int i = 1; i <= N; i++)
    {
        P[i][1] = dist[i]-1;
        if(P[i][1] == -1) P[i][1] = inf;
    }
    dijkstra(N, 0);
    for(int i = 1; i <= N; i++)
    {
        P[i][2] = dist[i]-1;
        if(P[i][2] == -1) P[i][2] = inf;
    }
    dijkstra(1, 1);
    for(int i = 1; i <= N; i++)
    {
        P[i][3] = dist[i]-1;
        if(P[i][3] == -1) P[i][3] = inf;
    }

    ans = P[N][0]+P[1][2];
    for(int i = 1; i <= M; i++)
    {
        auto[u, v, c, d] = ar[i];
        ans = min(ans, min(P[N][0], P[v][0]+  min(P[v][1], P[u][1]+c)) + min(P[1][2], P[v][2]+ min(P[v][3], P[u][3]+c)) +d);
    }
    cout << (ans > comp ? -1 : ans);
    return 0;
}


// sub 2 -> ok  after inverting you can still use the other way
// for each guy, have P(1, i) P(i, N) P(N, i) P(i, 1). For each V ans = +1, min(+2, P(U, N)+d+c), +3, min(+4, P(U,1)+d+c)
// sub 3 -> choose one and just get to the end
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...