Cod sursa(job #1705090)

Utilizator laurentiu.piciuPiciu Laurentiu laurentiu.piciu Data 19 mai 2016 21:59:30
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <iostream>
#include <fstream>

#define NMAX 100020

int N, M;

struct subset {
	int parent;
	int rank;
} v[NMAX];


/* Crearea seturilor initiale: la inceput fiecare nod reprezinta un arbore independent */
void makeSets() {
	for (int i = 0; i < N; ++i) {
		v[i].parent = i;
		v[i].rank = 0;
	}
}

int findSet(int node) {
	if (v[node].parent == node) {
		return node; /* Daca parintele este chiar nodul atunci am gasit subsetul*/
	}

	/* Altfel merg recursiv spre radacina, aplicand si compresia*/
	return (v[node].parent = findSet(v[node].parent));
}

/* Imbina 2 seturi rezultand unul singur */
void unionSets(int node1, int node2) {
	int set_x = findSet(node1);
	int set_y = findSet(node2);

	// Daca fac parte din acelasi subset - nu facem nimic
	if (set_x == set_y) {
		std::cerr << node1 << "; " << node2 << " fac parte din acelasi subset\n"; 
		return;
	}

	/* Incrementam rangul doar daca unul din noduri devine parintele celuilalt*/
	if (v[set_x].rank == v[set_y].rank) {
		v[set_y].parent = set_x;
		v[set_x].rank++;

	}

	/* Cine are rang mai mare devine parintele celuilalt */
	if (v[set_x].rank > v[set_y].rank) {
		v[set_y].parent = set_x;
	} else if (v[set_x].rank < v[set_y].rank) {
		v[set_x].parent = set_y;
	}
} 


int main() {
	std::ifstream f("disjoint.in");
	std::ofstream g("disjoint.out");

	f >> N >> M;

	makeSets();

	for (int i = 0; i < M; i++) {
		int tip_op, x, y;
		f >> tip_op >> x >> y;
		if (tip_op == 2) { 
			if (findSet(x) == findSet(y))
				g << "DA\n";
			else
				g << "NU\n";
		} else {
			unionSets(x, y);
		}
	}

	f.close(); g.close();

	return 0;
}