Submission #1326153

#TimeUsernameProblemLanguageResultExecution timeMemory
1326153SSKMFCommuter Pass (JOI18_commuter_pass)C++20
100 / 100
156 ms14548 KiB
#include <bits/stdc++.h>
using namespace std;

vector < pair <int , int> > adiacenta[100001];
int64_t distanta[3][100001] , minim[100001][2];
int ordine[100001];

inline void Dijkstra (const int numar_noduri , int nod , int64_t __distanta[])
{
    for (int indice = 1 ; indice <= numar_noduri ; indice++)
        { __distanta[indice] = 10000000000000000LL; }

    priority_queue < pair <int64_t , int> > candidati;
    candidati.emplace(__distanta[nod] = 0 , nod);
    while (!candidati.empty())
    {
        nod = candidati.top().second;
        if (__distanta[nod] != -candidati.top().first)
            { candidati.pop(); continue; }
        
        candidati.pop();
        for (auto& vecin : adiacenta[nod]) {
            if (__distanta[vecin.first] > __distanta[nod] + vecin.second)
                { candidati.emplace(-(__distanta[vecin.first] = __distanta[nod] + vecin.second) , vecin.first); }
        }
    }
}

int main ()
{
    ios :: sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int numar_noduri , numar_muchii , inceput[2] , sfarsit[2];
    cin >> numar_noduri >> numar_muchii >> inceput[0] >> sfarsit[0] >> inceput[1] >> sfarsit[1];

    while (numar_muchii--)
    {
        int nod[2] , cost;
        cin >> nod[0] >> nod[1] >> cost;
        adiacenta[nod[0]].emplace_back(nod[1] , cost);
        adiacenta[nod[1]].emplace_back(nod[0] , cost);
    }

    Dijkstra(numar_noduri , inceput[0] , distanta[0]);
    Dijkstra(numar_noduri , inceput[1] , distanta[1]);
    Dijkstra(numar_noduri , sfarsit[1] , distanta[2]);

    for (int indice = 1 ; indice <= numar_noduri ; indice++)
        { ordine[indice] = indice; }

    sort(ordine + 1 , ordine + numar_noduri + 1 , [] (int& optiune_1 , int& optiune_2) -> bool {
        return distanta[0][optiune_1] > distanta[0][optiune_2];
    });

    int64_t rezultat = distanta[1][sfarsit[1]];
    for (int indice = 1 ; indice <= numar_noduri ; indice++)
    {
        int& nod = ordine[indice];
        if (nod == sfarsit[0]) {
            minim[nod][0] = distanta[1][nod];
            minim[nod][1] = distanta[2][nod];
        } else {
            minim[nod][0] = 10000000000000000LL;
            minim[nod][1] = 10000000000000000LL;
        }

        for (auto& vecin : adiacenta[nod]) {
            if (distanta[0][vecin.first] == distanta[0][nod] + vecin.second)
            {
                rezultat = min(rezultat , distanta[1][nod] + minim[vecin.first][1]);
                rezultat = min(rezultat , distanta[2][nod] + minim[vecin.first][0]);
                minim[nod][0] = min(minim[nod][0] , minim[vecin.first][0]);
                minim[nod][1] = min(minim[nod][1] , minim[vecin.first][1]);
            }
        }

        if (minim[nod][0] != 10000000000000000LL) {
            minim[nod][0] = min(minim[nod][0] , distanta[1][nod]);
            minim[nod][1] = min(minim[nod][1] , distanta[2][nod]);
        }
    }

    cout << rezultat;
    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...