【算法】【并查集】并查集

并查集

  • 将两个集合合并;

  • 询问两个元素是否在一个集合当中;

  • 基本原理:每个集合用一颗树来维护,每个集合根节点的编号是当前集合的编号,每个节点存储它的父节点,p[x] 表示x的父节点;

  • 如何判断树根:

    • p[x] = x;
      
  • 查找:如何求x的集合编号:

    • 想判断某个点属于哪个集合,找到它所在的树的树根;
      while(p[x] != x) x = p[x];
      
    • 路径压缩(优化)
      第一次遍历,将遍历的这条链上的节点都指向根节点;
  • 合并:如何合并两个集合:

    • p[x]是x的集合编号,p[y]是y的集合编号;令p[x] = y;

实现

最重要的两个操作,合并和查找;难点在于如何将问题抽象出来,同时merge函数会根据具体问题细微的修改;
还有一步比较关键,就是初始化集合,初始化的时候每个节点的parent都指向该节点;

    vector<int> parent;
    void init(int n)
    {
        for(int i = 0; i < n; i++)
            parent.push_back(i);
    }
    int find(int x)
    {
        int root = x;
        while(parent[root] != root)
            root = parent[root];
        return root;
    }

    int merge(int a, int b)
    {
        int p_a = find(a);
        int p_b = find(b);
        if(p_a != p_b)
            parent[p_a] = p_b;   
        return p_a != p_b;
    }

posted @ 2020-08-17 14:22  NaughtyCoder  阅读(90)  评论(0)    收藏  举报