並查集

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;
    }
};
相關文章
相關標籤/搜索