Cod sursa(job #370737)

Utilizator titusuTitus C titusu Data 1 decembrie 2009 22:32:36
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
/*
 	paduri de multimi disjunte.
	Se dau n elemente, initial fiecare in propria multime. si m operatii
	1 x y - multimile din care fac parte x si y se reunesc
	2 x y - se verifica daca x si  y fac parte din aceesai multime.

Implementarea cu structuri arborescente:
	x,y fac parte din acceasi multime daca sunt in aclasi arbore, adica radacina arborelui lui x este identica cu radacina arborelui lui y
	
	In aceasta varianta aplicam ambele euritici
		reuniunea dupa rang - vezi disjoint1.cpp
		compresia drumurilor - vezi disjoint2.cpp
	OBS: prin compresie, este posibil ca inaltimea unui arbore sa se modifice (mai precis, sa scada). In program, nu mai corectam aceasta inaltime, astfel ca rang[x] devine practic o limita maxima pentru inaltimea arborelui cu radacina in x.
 */

using namespace std;
#include <fstream>
#define MAX 100010
int tata[MAX], n, rang[MAX];

void uneste(int , int);
int verifica(int , int);
int radacina(int v);


int main(){
	ifstream fin("disjoint.in");
	ofstream fout("disjoint.out");
	int m,op,x,y;
	fin>>n>>m;
	for(; m ; --m){
		fin>>op>>x>>y;
		if(op==1)
			uneste(x,y);
		else
			if(verifica(x,y))
				fout<<"DA\n";
			else
				fout<<"NU\n";
	}
	return 0;
}

void uneste(int x , int y){
	int rx = radacina(x);
	int ry = radacina(y);
	if(rang[rx]>rang[ry])
		tata[ry] = rx;
	else
		if(rang[rx]<rang[ry])
			tata[rx] = ry;
		else
			tata[ry] = rx, rang[rx]++;
}

int verifica(int x, int y){
	return radacina(x) == radacina(y);
}

int radacina(int x){
	int y=x,tmp;
	while(tata[x])
		x = tata[x];
	while(y-x)
		tmp = tata[y], tata[y] = x, y = tmp;
	return x;
}