Pagini recente » Cod sursa (job #2969749) | Cod sursa (job #1678032) | Cod sursa (job #987265) | Cod sursa (job #732664) | Cod sursa (job #2938883)
//Rezolvarea se bazeaza pe reuniunea dupa rang adica:
//Atunci cand reunim cele 2 multimi
//legam arborele mai mare la arborele mai mic
//(arborii din care fac parte elementul X resp elementul Y) si pe
//Compresia drumurilor adica atunci cand facem o interogare dupa ce am aflat
//multimea in care se afla x mai parcurgem o data drumul de la x la radacina
// si unim toate nodeurile direct de radacina (ne ajutam de vectorul de tati)
#include <iostream>
#include <fstream>
using namespace std;
ifstream f("disjoint.in");
ofstream g("disjoint.out");
int N, M;
int* tata=new int[N+1];;
int* h=new int[N+1];;
int Find(int nod)
{
//inseamna ca este radacina
if(tata[nod] == 0) {
return nod;
}
//memoram tatal fiecarui nod
return tata[nod] = Find(tata[nod]);
}
void Union(int x, int y) {
//Atunci cand reunim cele 2 multimi
//legam arborele mai mare la arborele mai mic
// (arborii din care fac parte elementul X resp elementul Y)
// Inaltimile arborilor le putem obtine din vectorul h
int tataX = Find(x);
int tataY = Find(y);
// Comparam inaltimea arborilor cu radacinile tataX resp tataY
if(h[tataX] > h[tataY]) {
// In acest caz, atasam la arborele din care face parte X (arborele mai mare) arborele din care face parte Y (arborele mai mic)
tata[tataY] = tataX;
} else if(h[tataX] < h[tataY]) {
// Invers
tata[tataX] = tataY;
} else {
// Nu conteaza pe care dintre arbori il legam la celalalt, insa trebuie sa updatam inaltimea arborelui rezultat si sa o incrementam cu 1
tata[tataY] = tataX;
h[tataX]++;
}
}
int main()
{
f>>N>>M;
//initializam vectorul de tati cu 0 si vectorul de inaltimi cu 1
for(int i = 0; i<= N; i++) {
tata[i] = 0;
h[i] = 1;
}
for(int i = 1; i <= M; i++) {
int cod, x, y;
f>> cod >> x >> y;
if(cod == 1) {
Union(x, y);
}
else if(cod == 2) {
if (Find(x)== Find(y))
g<<"DA\n";
else
g<<"NU\n";
}
}
return 0;
}