Pagini recente » Cod sursa (job #1294808) | Cod sursa (job #1602150) | Cod sursa (job #566495) | Cod sursa (job #849360) | Cod sursa (job #370737)
Cod sursa(job #370737)
/*
paduri de multimi disjunte.
Se dau n elemente, initial fiecare in propria multime. si m operatii
1 x y - multimile din care fac parte x si y se reunesc
2 x y - se verifica daca x si y fac parte din aceesai multime.
Implementarea cu structuri arborescente:
x,y fac parte din acceasi multime daca sunt in aclasi arbore, adica radacina arborelui lui x este identica cu radacina arborelui lui y
In aceasta varianta aplicam ambele euritici
reuniunea dupa rang - vezi disjoint1.cpp
compresia drumurilor - vezi disjoint2.cpp
OBS: prin compresie, este posibil ca inaltimea unui arbore sa se modifice (mai precis, sa scada). In program, nu mai corectam aceasta inaltime, astfel ca rang[x] devine practic o limita maxima pentru inaltimea arborelui cu radacina in x.
*/
using namespace std;
#include <fstream>
#define MAX 100010
int tata[MAX], n, rang[MAX];
void uneste(int , int);
int verifica(int , int);
int radacina(int v);
int main(){
ifstream fin("disjoint.in");
ofstream fout("disjoint.out");
int m,op,x,y;
fin>>n>>m;
for(; m ; --m){
fin>>op>>x>>y;
if(op==1)
uneste(x,y);
else
if(verifica(x,y))
fout<<"DA\n";
else
fout<<"NU\n";
}
return 0;
}
void uneste(int x , int y){
int rx = radacina(x);
int ry = radacina(y);
if(rang[rx]>rang[ry])
tata[ry] = rx;
else
if(rang[rx]<rang[ry])
tata[rx] = ry;
else
tata[ry] = rx, rang[rx]++;
}
int verifica(int x, int y){
return radacina(x) == radacina(y);
}
int radacina(int x){
int y=x,tmp;
while(tata[x])
x = tata[x];
while(y-x)
tmp = tata[y], tata[y] = x, y = tmp;
return x;
}