Pagini recente » Cod sursa (job #435586) | Cod sursa (job #3214009) | Cod sursa (job #559333) | Cod sursa (job #3164180) | Cod sursa (job #2942722)
#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();
}