Pagini recente » Cod sursa (job #2265642) | Cod sursa (job #1298954) | Cod sursa (job #1143388) | Cod sursa (job #1148477) | Cod sursa (job #2947646)
//Complexitatea este O(log*n)
//IDEE
//- reprezentam fiecare multime ca pe un arbore cu radacina
//Pentru operatie de tip 2
// -parcurgem arborele in sus din ambele elemente
// si daca la sfarsit ajungem in aceeasi radacina atunci elementele noastre se afla in aceeasi multime
//Pentru operatie de tip 1
// -determinam radacinile celor 2 arbori si le conectam printr-o muchie.
#include<fstream>
#include<stdio.h>
using namespace std;
ifstream f("disjoint.in");
ofstream g("disjoint.out");
int tt[100001], rang[100001];
//Pentru fiecare multime tinem minte inaltimea arborelui care reprezinta acea multime(rang)
int n, m;
int find(int x){
int r, y;
//merg in sus pe arbore pana gasesc un nod care pointeaza catre el insusi
//practic aflam in ce multime se afla nodul
r = x;
while(tt[r] != r)
r = tt[r];
//unim toate nodurile direct de radacina(intr-un singur pas sa ajungem la radacina)
while(tt[x]!=x){ //compresia drumurilor
y = tt[x];
tt[x] = r;
x = y;
}
return r;
}
void unite(int x, int y) //reuniune dupa rang
{
//unesc multimea cu rang mai mic de cea cu rang mai mare
if (rang[x] > rang[y])
tt[y] = x;
else tt[x] = y;
//in caz ca rangurile erau egale atunci cresc rangul noii multimi cu 1
if (rang[x] == rang[y])
rang[y]++;
}
int main()
{
f >> n >> m;
//initial fiecare nod arata catre el insusi iar rangul fiecarui arbore este 1
for (int i = 1; i <= n; i++){
tt[i] = i;
rang[i] = 1;
}
for (int i = 1; i <= m; i++)
{
int x, y, cod;
f >> cod >> x >> y;
if (cod == 2)
//verific daca radacina arborilor in care se afla x respectiv y este egala
if (find(x) == find(y))
g << "DA" << endl;
else
g << "NU" << endl;
else //pentru cod==1, unesc radacinile arborilor corespunzatori multimilor nodurilor x respectiv y
unite(find(x), find(y));
}
return 0;
}