Submission #1324611

#TimeUsernameProblemLanguageResultExecution timeMemory
1324611SSKMFTorrent (COI16_torrent)C++20
100 / 100
1227 ms25876 KiB
#include <bits/stdc++.h>
using namespace std;

pair <int , int> interzis;
vector <int> adiacenta[300001];
int ordine[300001] , raspuns[300000][2];

inline bool GetPath (const int nod , const int dorit , const int sursa)
{
    if (nod == dorit)
    {
        ordine[++ordine[0]] = nod;
        return true;
    }

    for (auto& vecin : adiacenta[nod]) {
        if (vecin != sursa) {
            if (GetPath(vecin , dorit , nod))
            {
                ordine[++ordine[0]] = nod;
                return true;
            }
        }
    }

    return false;
}

inline int Calcul (const int nod , const int sursa)
{
    vector <int> candidati;
    for (auto& vecin : adiacenta[nod]) {
        if (vecin != sursa && !((nod == interzis.first && vecin == interzis.second) || (nod == interzis.second && vecin == interzis.first)))
            { candidati.push_back(Calcul(vecin , nod) + 1); }
    }

    sort(candidati.begin() , candidati.end() , greater <int> ());

    int maxim = 0;
    for (int indice = 0 ; indice < (int)candidati.size() ; indice++)
        { maxim = max(maxim , candidati[indice] + indice); }

    return maxim;
}

inline int Search (const int inceput , const int limita , const int tip)
{
    int nod = 1 , stanga = 1 , dreapta = ordine[0] - 1;
    while (stanga <= dreapta)
    {
        const int candidat = (stanga + dreapta) >> 1;
        if (raspuns[nod][tip] == -1) {
            interzis = {ordine[candidat] , ordine[candidat + 1]};
            raspuns[nod][tip] = Calcul(inceput , 0);
        }

        if (raspuns[nod][tip] <= limita) {
            if (tip == 0) { nod += candidat - stanga + 1; stanga = candidat + 1; }
            else { nod++; dreapta = candidat - 1; }
        } else {
            if (tip == 0) { nod++; dreapta = candidat - 1; }
            else { nod += candidat - stanga + 1; stanga = candidat + 1; }
        }
    }

    return (tip == 0 ? dreapta : stanga);
}

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

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

    for (int indice = 1 ; indice < numar_noduri ; indice++)
    {
        int nod[2]; cin >> nod[0] >> nod[1];
        adiacenta[nod[0]].push_back(nod[1]);
        adiacenta[nod[1]].push_back(nod[0]);
    }

    GetPath(inceput[0] , inceput[1] , 0);

    for (int indice = 1 ; indice < ordine[0] ; indice++)
        { raspuns[indice][0] = raspuns[indice][1] = -1; }

    int stanga = 0 , dreapta = numar_noduri;
    while (stanga <= dreapta)
    {
        const int candidat = (stanga + dreapta) >> 1;
        const int limita_1 = Search(inceput[0] , candidat , 1);
        const int limita_2 = Search(inceput[1] , candidat , 0);
        if (limita_1 <= limita_2) { dreapta = candidat - 1; }
        else { stanga = candidat + 1; }
    }

    cout << stanga;
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...