Cod sursa(job #2942722)

Utilizator widzAndrei-Daniel Tava widz Data 19 noiembrie 2022 23:24:18
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.01 kb
#include <fstream>
using namespace std;


/*
 *		2) Disjoint
 *
 *			Retinem multimile drept structuri arborescente, folosind un vector de tati.
 *		-Pentru a determina daca doua elemente sunt in aceeasi multime, se parcurg tatii pana
 *		 la radacina. Complexitatea este in cel mai rau caz O(N), dar de obicei va fi O(logN)
 *		-Pentru reuniunea a doua multimi, se leaga o radacina de cealalta, din nou complexitatea
 *		 fiind reprezentata de determinarea tatalui,deci tot O(logN) -> O(N).
 *
 *			Operatiile se pot optimiza si mai mult pentru a asigura ca worst-case de O(N) nu se atinge
 *		 niciodata, precum legarea arborelui mai mic la cel mai mare mereu(necesita stocarea
 *		 inaltimilor) sau caching pentru radacina unui nod pentru a amortiza complexitatea.
 */

class DisjointSet{
private:
	const int _size;
	int* _father;
	int* _rank;

	int getRoot(int el){
		while(_father[el - 1] != el){
			el = _father[el - 1];
		}
		return el;
	}
public:
	DisjointSet(const int p_size) : _size(p_size){
		_father = new int[_size];
		_rank = new int[_size];
		for(int i = 0; i<p_size;++i){
			_father[i] = i + 1;
			_rank[i] = 1;
		}
	}
	void merge(const int x, const int y){
		const int root_y = getRoot(y);
		const int root_x = getRoot(x);
		if(_rank[root_x - 1] > _rank[root_y - 1]){
			_father[root_y - 1] = root_x;
		}
		else{
			_father[root_x - 1] = root_y;
			if(_rank[root_x - 1] == _rank[root_y - 1]){
				_rank[root_y - 1] = _rank[root_x - 1] + 1;
			}
		}
	}

	bool check(const int x, const int y){
		return getRoot(x) == getRoot(y);
	}
	~DisjointSet(){
		delete[] _father;
	}
};

int main(){
	ifstream in("disjoint.in");
	ofstream out("disjoint.out");
	int n, m;
	in >> n >> m;
	DisjointSet forest(n);
	for(int i=0; i<m; ++i){
		int cmd, x, y;
		in >> cmd >> x >> y;
		switch(cmd)
		{
		case 1:
			forest.merge(x, y);
			break;

		case 2:
			out << (forest.check(x, y) ? "DA\n" : "NU\n");
			break;

		default:
			break;
		}
	}
	in.close();
	out.close();
}