Cod sursa(job #2751981)

Utilizator ApostolIlieDanielApostol Daniel ApostolIlieDaniel Data 16 mai 2021 10:58:22
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.74 kb
#include <bits/stdc++.h>

using namespace std;

/// varianta cu compresie -> O(NlogN)
/// daca mai adaugam si unirea de la mai mic la mai mare => O(Nlog(logN))

const int MAX_N = 1e5;
int n;

int sef[1 + MAX_N];
int marime[1 + MAX_N];


int gaseste_sef_rec (int x) {
    if (sef[x] == x)
        return x;
    sef[x] = gaseste_sef_rec (sef[x]);
    return sef[x];
}

void uneste (int x, int y) { /// functie care uneste x si y
    int tx = gaseste_sef_rec (x);
    int ty = gaseste_sef_rec (y);
    if (tx != ty) { /// daca x si y nu sunt deja in aceeasi multime
        /// vrem sa lipim ala mai mic la ala mai mare
        if (marime[tx] < marime[ty])
            swap (tx, ty);
        /// acum ala mai mare este tx si ala mai mic ty
        sef[ty] = tx;
        marime[tx] += marime[ty];
        marime[ty] = 0;
    }
}

void initializare () {
    for (int i = 1; i <= n; i++) {
        sef[i] = i; /// fiecarui element ii dam cate o multime in care el este sef suprem
        marime[i] = 1;
    }
}

void query (int x, int y) { /// daca x si y sunt in aceeasi multime
    int tx = gaseste_sef_rec (x);
    int ty = gaseste_sef_rec (y);
    if (tx == ty) {
        cout << "DA\n";
    }
    else {
        cout << "NU\n";
    }
}


int main () {
    freopen ("disjoint.in", "r", stdin);
    freopen ("disjoint.out", "w", stdout);
    ios::sync_with_stdio (false);
    cin.tie (0); cout.tie (0);
    int m;
    cin >> n >> m;
    initializare ();
    for (int i = 1; i <= m; i++) {
        int tip, x, y;
        cin >> tip >> x >> y;
        if (tip == 1) { /// operatia de unire
            uneste (x, y);
        }
        else { /// query
            query (x, y);
        }
    }
    return 0;
}