• + 0 comments

    DFS on subset tree

    class disjoint_set {
    public:
        vector<int> parent, size;
        disjoint_set(int n) {
            parent.resize(n);
            iota(parent.begin(), parent.end(), 0);
            size.resize(n, 1);
        }
        int find(int x) {
            if (x != parent[x]) parent[x] = find(parent[x]);
            return parent[x];
        }
        bool Union(int x, int y) {
            int xRep = find(x), yRep = find(y);
            if (xRep == yRep) return false;
            if (size[xRep] <= size[yRep]) {
                parent[xRep] = yRep;
                size[yRep] = size[yRep] + size[xRep];
            }
            else {
                parent[yRep] = xRep;
                size[xRep] = size[xRep] + size[yRep];
            }
            return true;
        }
    };
    
    void travel(const vector<long>& D, vector<bool> subset, disjoint_set partition, int level, int components, int& total, long nodeSet) {
        int newComponents = components;
        if (subset[level] == true) {
            nodeSet = nodeSet | D[level];
            ++newComponents;
            for (int i=0; i <= level; ++i) {
                if (subset[i] and (D[i] & D[level]) != 0 and partition.Union(i, level) == true) {
                    --newComponents;
                }
            }
            total = total + 64 - __builtin_popcountl(nodeSet) + newComponents;
        }
        if (level == D.size() - 1) return;
        travel(D, subset, partition, level + 1, newComponents, total, nodeSet);
        subset[level + 1] = true;
        travel(D, subset, partition, level + 1, newComponents, total, nodeSet);
    }
    
    
    int findConnectedComponents(int N, const vector<long>& D) {
        int total = 64;
        vector<bool> subset(N);
        disjoint_set partition(N);
        travel(D, subset, partition, 0, 0, total, 0);
        subset[0] = true;
        travel(D, subset, partition, 0, 0, total, 0);
        return total;   
    }