Cod sursa(job #3275410)

Utilizator jumaracosminJumara Cosmin-Mihai jumaracosmin Data 10 februarie 2025 14:14:41
Problema Paduri de multimi disjuncte Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.67 kb
/*
    Elementele sunt impartite in multimi disjuncte care ne permit efectuarea unor operatii.
    La baza stau grafurile, cu operatiile:

    1) stabilirea submulțimii din care face parte un anumit element
    2) pentru două elemente date, reuniunea submulțimilor din care fac parte aceste elemente

    O modalitate eficientă de gestionare a submulțimilor și a operațiilor cu acestea
    este utilizarea unor structuri arborescente numite pădure de mulțimi disjuncte, în care:

    1) fiecare submulțime este reprezentată printr-un arbore cu rădăcină
    2) rădăcina fiecărui arbore este reprezentantul submulțimii
    3) operațiile se implementează astfel:

        I)  stabilirea submulțimii din care face parte un anumit element constă de regulă
            în identificarea rădăcinii arborelui din care face parte

        II) reuniunea a două submulțimi constă în concatenarea arborilor: rădăcina unuia
            dintre arbore i se stabilește devine tată pentru rădăcina celuilalt


    Gestionarea arborilor se poate face prin intermediul unui vector de tați
        father[k] = k, daca k este radacina (si reprezentant)
        father[k] = tatal lui k


*/

#include <bits/stdc++.h>

using namespace std;

ifstream fin("disjoint.in");
ofstream fout("disjoint.out");

const int SIZE = 100005;

int father[SIZE];
int n, m;

//vom folosi o functie pentru a obtine radacina unui element x
int getFather(int);

void read();
void solve();

int main()
{
    read();
    solve();
    return 0;
}

void read()
{
    fin >> n >> m;
    //fiecare element este radacina
    for(int i = 1; i <= n; ++i)
        father[i] = i;
}

//aflam radacina
int getFather(int x)
{
    if(father[x] != x)
        //duc x-ul cat mai aproape de radacina
        father[x] = getFather[father[x]];
    //ajung la radacina
    return father[x];
}

void solve()
{
    for(int i = 1; i <= m; ++i)
    {
        int op, x, y;
        fin >> op >> x >> y;
        //luam radacinile (reprezentantii)
        int father_x, father_y;
        father_x = getFather(x);
        father_y = getFather(y);
        //operatiile sunt de 2 tipuri:
        //op 1: JOIN (sa se reuneasca multimile)
        if(op == 1)
        {
            //pentru a reuni doua multimi legam una dintre radacini la cealalta
            father[father_y] = father_x;
        }
        //op 2: Sa se raspunda la query-ul "Se afla elementele x si y in aceeasi multime?
        else
        {
            if(father_x == father_y)
                fout << "DA";
            else
                fout << "NU";
            fout << "\n";
        }
    }
}