Connecting Graph I II III (Lintcode 589 - 591)

这类题是典型的Union Find 题目。对于I,直接写出基本的Union 和 Find就行。

对于II,题目要求返回query点的connected components。直接写一个for loop来查找会超时。所以这样的问题,应当首先想到从parent入手。用第二个map,来存每个node的connected components个数。而合并时,应当将parents的connected components个数,加起来。即number of cc (new father) += number of cc (old father)。

class ConnectingGraph2 {
private:
    unordered_map mp;
    unordered_map count;
public:

    int find_(int i){
        int parent = mp[i];
        while(parent != mp[parent]){
            parent = mp[parent];
        }
        int next;
        while(i != mp[i]){
            next = mp[i];
            mp[i] = parent;
            i = next;
        }
        return parent;
    }

    ConnectingGraph2(int n) {
        // initialize your data structure here.
        for(int i=0; i

III 更为简单一点,其实就是求(节点数 - 非环边数), 用一个cnt,先union时加一即可。

class ConnectingGraph3 {
private:
    unordered_map mp;
    int cnt;
    int num;
public:
    
    int find_(int i){
        int parent = mp[i];
        while(parent != mp[parent]){
            parent = mp[parent];
        }
        int next;
        while(i != mp[i]){
            next = mp[i];
            mp[i] = parent;
            i = next;
        }
        return parent;
    }

    void union_(int p, int q){
        int p_parent = find_(p), q_parent = find_(q);
        if(p_parent != q_parent){
            mp[p_parent] = q_parent;
            cnt++;
        }
    }
    
    ConnectingGraph3(int n) {
        // initialize your data structure here.
        for(int i=1; i<=n; i++){
            mp[i] = i;
        }
        cnt = 0; 
        num = n;
    }
        
    void  connect(int a, int b) {
        // Write your code here
        union_(a, b);
    }

    int query() {
        // Write your code here
        return num - cnt;
    }
};

你可能感兴趣的:(Connecting Graph I II III (Lintcode 589 - 591))