class UnionFindSets { int *father, *rank; public: UnionFindSets(int N) { father = new int[N], rank = new int[N]; for(int x=0; x<N; x++) father[x] = x, rank[x] = 1; } int FindSets(int x) { if(x != father[x]) father[x] = FindSets(father[x]); //這個回溯時的壓縮路徑是精華 return father[x]; } bool SameSets(int x, int y) { return FindSets(x) == FindSets(y); } void UnionSets(int x, int y) { if((x = FindSets(x)) == (y = FindSets(y))) return; if(rank[x] <= rank[y]) father[x] = y, rank[y] += rank[x]; else father[y] = x, rank[x] += rank[y]; } ~UnionFindSets() { delete[] father, delete[] rank; } };
class Tree { int data; Tree *ll, *rr; void append(Tree *t) { if(t->data < data) { if(!ll) ll = t; else ll->append(t); } if(t->data > data) { if(!rr) rr = t; else rr->append(t); } } public: void init(int a) { data = a; ll = rr = NULL; } void merge(Tree *tree, Tree *same[]) { if(this == tree) return; if(ll) { ll->merge(tree, same); ll = NULL; } if(rr) { rr->merge(tree, same); rr = NULL; } tree->append(this); same[data] = tree; } }; class UnionFindSets { Tree *_buf, **same; public: UnionFindSets(int N) { _buf = new Tree [N]; same = new Tree *[N]; for(int i=0; i<N; i++) { same[i] = &_buf[i]; same[i]->init(i); } } bool SameSets(int X, int Y) { return same[X] == same[Y]; } void UnionSets(int X, int Y) { same[X]->merge(same[Y], same); } ~UnionFindSets() { delete[] same; delete[] _buf; } };