Cod sursa(job #2805865)

Utilizator namesurname01Name Surname namesurname01 Data 22 noiembrie 2021 02:50:26
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.82 kb
#include <stdio.h>

using namespace std;
FILE* f, * g;
int n, m, tata[100002], rang[100002];
/*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*/

int multime(int x)
{
    int rad = x, aux;
    while (rad != tata[rad])///cat timp nu am ajuns la radacina arborelui
        rad = tata[rad];///determinam in ce multime se afla nodul x
    ///rad- reprezinta radacina nodului x
    while (x != tata[x])///parcurgem inca o data drumul de la x la radacina si unim nourile noduri cu radacina rad
    {//fix ce ne-a prezentat la FA
        aux = tata[x];
        tata[x] = rad;
        x = aux;
    }
    return rad;
}

void reunesc(int x, int y)
{
    x = multime(x);
    y = multime(y);
    if (x == y) return;
    if (rang[x] < rang[y])
        tata[x] = y;
    else
        tata[y] = x;
    if (rang[x] == rang[y])
        ++rang[x];
}

void read()
{
    int i, caz, x, y;
    fscanf(f, "%d %d", &n, &m);
    for (i = 1;i <= n;++i)
        tata[i] = i;
    for (i = 1;i <= m;++i)
    {
        fscanf(f, "%d %d %d", &caz, &x, &y);
        if (caz == 1)///reunirea multimilor in care se afla x si a celor in care se afla y
            reunesc(multime(x), multime(y));
        else
        {
            if (multime(x) == multime(y))///sea afla x si y in aceiasi multime
                fprintf(g, "DA\n");
            else
                fprintf(g, "NU\n");
        }
    }
}
int main()
{
    int i, caz;
    f = fopen("disjoint.in", "r");
    g = fopen("disjoint.out", "w");
    read();
    fclose(f);
    fclose(g);
    return 0;
}