LintCode 590. Connecting Graph II (并查集经典题!!!)

  1. Connecting Graph II
    Given n nodes in a graph labeled from 1 to n. There is no edges in the graph at beginning.

You need to support the following method:

connect(a, b), an edge to connect node a and node b
query(a), Returns the number of connected component nodes which include node a.
Example
5 // n = 5
query(1) return 1
connect(1, 2)
query(1) return 2
connect(2, 4)
query(1) return 3
connect(1, 4)
query(1) return 3

思路:
经典并查集算法
注意:

  1. 在query()里面必须返回nodeNum[find(a)]而不是nodeNum[father[a]]。原因是当a的component跟另一个component合并时,father[a]可能还没更新。举例如下:
    input case:
    ConnectingGraph2(5)
    query(1)
    connect(1, 2)
    query(1)
    connect(2, 4) – connect(2,4)后,1的father[]还未更新
    query(1) – 如果直接返回nodeSum[father[1]]则出错!!!
    connect(1, 4)
    query(1)

同样,connect()里面也不能用father[a],必须用find(a)。
2) path compression的条件也可以写成while(x2!=father[x2]),但稍慢。
3) connect()里面是father[fatherA]=fatherB,不要写成father[a]=father[b]或father[a]=fatherB之类的。

代码如下:

class ConnectingGraph2 {
public:
    /*
    * @param n: An integer
    */
    ConnectingGraph2(int n) {
        father.resize(n + 1);
        nodeNum.resize(n + 1);
        for (int i = 1; i <= n; ++i) {
            father[i] = i;
            nodeNum[i] = 1;
        }
    }

    /*
     * @param a: An integer
     * @param b: An integer
     * @return: nothing
     */
    void connect(int a, int b) {
        int rootA = find(a);   //不能用father[a]
        int rootB = find(b);   //不能用father[b]
        if (rootA != rootB) {
            father[rootA] = rootB;
            nodeNum[rootB] += nodeNum[rootA];
        }
    }

    /*
     * @param a: An integer
     * @return: An integer
     */
    int query(int a) {
    //    return nodeNum[father[a]];    //wrong!!!
        return nodeNum[find(a)];
    }
    
private:
    vector<int> father;
    vector<int> nodeNum;
    
    //find the root of x
    int find(int x) {
        int x2 = x;
        
        if (father[x] == x) return x;
        
        while(father[x] != x) {
            x = father[x];
        }
        
        //path compression
        while (x2 != x) {
            int temp = father[x2];
            father[x2] = x;
            x2 = temp;
        }
        
        return x;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值