Cod sursa(job #1820471)

Utilizator StefansebiStefan Sebastian Stefansebi Data 1 decembrie 2016 19:35:13
Problema Paduri de multimi disjuncte Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.67 kb
#include<fstream>
#include<map>
using namespace std;
ifstream fin("disjoint.in");
ofstream fout("disjoint.out");

typedef struct Node {
	int data;
	Node* parent;
	int rank;
}Node;

/*
The nodes for each element
*/
map<int, Node*> elements = {};

/*
Create a set with one element
*/
void makeSet(int data) {
	Node* node = new Node;
	node->data = data;
	node->rank = 0;
	node->parent = node;
	elements[data] = node;
}

/*
Finds the represantative of the set recursively
*/
Node* findSet(Node* node) {
	Node* parent = node->parent;
	if (parent == node) {
		return parent;
	}
	node->parent = findSet(node->parent);
	return node->parent;
}

/*
Combines two sets to one
union by rank
*/
void unionSets(int data1, int data2) {
	Node* node1 = elements[data1];
	Node* node2 = elements[data2];

	Node* parent1 = findSet(node1);
	Node* parent2 = findSet(node2);

	if (parent1->data == parent2->data) {
		return; //they are part of the same set
	}

	if (parent1->rank >= parent2->rank) {
		//increment rank only if they have the same rank
		parent1->rank = parent1->rank == parent2->rank ? parent1->rank + 1 : parent1->rank;
		parent2->parent = parent1;
	}
	else {
		parent1->parent = parent2;
	}
}

/*
Finds the representative element of the set
*/
int findSet(int data) {
	return findSet(elements[data])->data;
}



int main() {
	int n, m;
	fin >> n >> m;

	for (int i = 1; i <= n; i++) {
		makeSet(i);
	}
	for (int i = 1; i <= m; i++) {
		int a, b, c;
		fin >> a >> b >> c;
		if (a == 1) {
			unionSets(b, c);
		}
		else {
			if (findSet(b) == findSet(c)) {
				fout << "DA\n";
			}
			else {
				fout << "NU\n";
			}
		}
	}
}