Cod sursa(job #2535197)

Utilizator ArkhamKnightyMarco Vraja ArkhamKnighty Data 31 ianuarie 2020 17:13:41
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.46 kb
// PREFATA DE 𝓥𝓡𝓐𝓙𝓐 𝓜𝓐𝓡𝓒𝓞
#include <fstream>

using namespace std;

ifstream cin("disjoint.in");
ofstream cout("disjoint.out");

int v[100001], n, m;

/* v[i] - parintele nodului i
    Stramos independent comun - radacina arborelui nostru, nodul care nu are stramosi,
                                nodul care isi este stramos siesi

    Ideea este ca noi, in cazul 2, vom stabili daca cele doua noduri citite au acelasi
    stramos independent comun
    Pentru cazul 1, vom lega stramosul independent al lui x lui stramosului independent al lui y,
    astfel incat y devine stramosul independent al lui x

    Idee in plus

     Compresia drumurilor: Atunci cand facem o interogare,
     dupa ce am aflat in ce multime se afla nodul x,
     mai parcurgem o data drumul de la x la radacina si unim toate nodurile direct de radacina.

     Astfel data viitoare cand vom avea o interogare pentru unul din aceste noduri
      vom ajunge intr-un singur pas la radacina.

     Este posibil ca atunci cand facem compresia drumurilor inaltimea arborelui sa se modifice,
     insa nu actualizam rangul (in cazul in care este folosita si prima euristica).

     In acest caz, acel rang va deveni practic o limita superioara a inaltimii arborelui.

*/
void citire()
{
    cin >> n >> m;

    for(int i = 1 ; i <= n ; i++)
        v[i] = i; // initial el este propriul parinte

}

void rez()
{
    int t, x, y, aux;

    for(int i = 1 ; i <= m ; i++)
    {
        cin >> t >> x >> y;

        while(x != v[x]) aux = v[v[x]], v[x] = aux, x = aux; // mergem in sus pe arbore
        // x = aux, inseamna ca x devine parintele lui v[x], adica urcam pe arbore
        // si la fiecare nivel, setam ca parinte curent + compresam drumul

        while(y != v[y]) aux = v[v[y]], v[y] = aux, y = aux; // mergem in sus pe arbore
        // y = aux, inseamna ca x devine parintele lui v[y], adica urcam pe arbore
        // si la fiecare nivel, setam ca parinte curent + compresam drumul

        // in urma celor doua while, x si y au ajuns fiecare la stramosul lor INDEPENDENT

        if(t == 1) v[x] = y; // parintele stramosului independent al lui x este y

        else
            (x == y) ? // x este egal cu y
            // daca au acelasi stramos INDEPENDENT comun, inseamna ca se afla in aceeasi multime
            cout << "DA \n" : cout << "NU \n";





    }
}

int main()
{
    citire();
    rez();
    return 0;
}