Cod sursa(job #2947646)

Utilizator bbia17Baicoianu Bianca bbia17 Data 26 noiembrie 2022 15:27:15
Problema Paduri de multimi disjuncte Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.95 kb
//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;
}