Submission #1271666

#TimeUsernameProblemLanguageResultExecution timeMemory
1271666cokalhadoOlympic Bus (JOI20_ho_t4)C++20
0 / 100
1095 ms59300 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()
{
    srand(time(0));
    int absolute_global_answer = -1;
    int t = 100;
    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);
    }
    while(t--)
    {
        ans = inf;
        for(int i = 1; i <= M; i++)
        {
            auto[u, v, c, d] = ar[i];
            c = rand()*rand()+rand()+rand()+rand()+1;
            ar[i] = make_tuple(u, v, c, d);
            g[u][0].push_back({v, c});
            g[v][1].push_back({u, c});
        }

        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;
        }

        if(P[N][0] >= 0 && P[1][2] >= 0)
        {
            cout << 0;
            return 0;
        }

        // for(int i = 1; i <= N; i++)
        // {
            // cout << "i " << i << " P " << P[i][0] << " " << P[i][1] << " " << P[i][2] << " " << P[i][3] << endl;
        // }

        ans = inf;
        for(int i = 1; i <= M; i++)
        {
            auto[u, v, c, d] = ar[i];
            // if(i > 2) cout << "i " << i << " " << " u " << u << " v " << v << " ";
            // for each guy, have P(1, i) P(i, N) P(N, i) P(i, 1)
            if(P[v][0] >= 0 && P[u][1] >= 0)
            {
                if(P[1][2] >= 0)
                {
                    if(P[1][2] != P[u][2]+c+P[v][3])
                    {
                        ans = min(ans, d);
                        // cout << "d " << d << " r2" << endl;
                        continue;
                    }
                    else continue;
                }
            }
            if(P[v][2] && P[u][3])
            {
                if(P[N][0] >= 0)
                {
                    if(P[N][0] != P[u][0]+c+P[u][1])
                    {
                        ans = min(ans, d);
                        // cout << "d " << d << " r3" << endl;
                        continue;
                    }
                    else continue;
                }
                // for each guy, have P(1, i) P(i, N) P(N, i) P(i, 1)
            }
            if(P[v][0] >= 0 && P[u][1] >= 0 && P[v][2] >= 0 && P[u][3] >= 0)
            {
                ans = min(ans, d);
                // cout << "d " << d << " r1" << endl;
                continue;
            }
        }
        absolute_global_answer = max(absolute_global_answer, ans);
    }
    cout << (absolute_global_answer > comp ? -1 : absolute_global_answer);
    return 0;



    // 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
// maybe do P(1, i) P(i, N) P(N, i) P(i, 1) be the number of ways to get from a place to another
// then you can see wether there's another way

// make all c have rand(), see if the best path goes through me



// for each guy, have P(1, i) P(i, N) P(N, i) P(i, 1)
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...