并查集:不相交集合

并查集是一种树型的数据结构,其保持着用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。支持三种操作:

  • Make-Set : 用于建立单元素集合。
  • Find-Set:确定元素属于哪一个子集。它可以被用来确定两个元素是否属于同一子集。
  • Union:将两个子集合并成同一个集合。

1.并查集的数组表示

//x表示元素,s[x]表示x所属集合
int s[N];
Make-Set(x){
    s[x] = x;
}
Find-Set(x){
    return s[x];
}
//将y在所属集合并入x所属集合
Union(x,y){
    int temp = s[y];
    //遍历所有元素,将和y在同一集合的元素并入x所属集合
    for(int i=0;i<N;i++){
        if(s[i]==temp){
            s[j] = s[x];
        }
    }
}

Kruskal算法中我用的就是这种方法.当然也可以用链表表示,就不详细介绍了.思路如下:

//所需数据结构
class Node;
class Head{
    Node* head;
    Node* tail;
};
class Node{
    Head* head;
    char vertex;
    Node* next;
};

2.并查集深林

用有根树表示集合,树中的每一个结点代表一个成员,每棵树代表一个集合.在一个并查集深林中,每个成员仅指向其父结点,每棵树的树根是集合的代表,它的父结点指向自己.

Make-Set(x)
    x.p = x
    x.rank = 0
//按秩合并
Union(x,y)
    Link(Find-Set(x),Find-Set(y))
Link(x,y)
    if x.rank > y.rank
        y.p = x
    else
        x.p = y
        if x.rank==y.rank
            y.rank = y.rank +1
//路径压缩
Find-Set(x)
    if x ≠ x.p
        x.p = Find-Set(x.p)
    return x.p

它使用O(n)的空间(为元素数量),单次操作的均摊时间为O(α(n)),α(n)≤4,总的运行时间为O(mα(n)),m为所有操作的次数.

实现:

#include<iostream>
#include<vector>
class Node{
    int x;
    int rank = 0;
    Node* p;
    Node(int m):x(m){}
};
vector<Node> S;
void Make-Set(x){
    Node node = Node(x);
    node.p = &node;
    S.push_back(node);
}
Node* Find-Set(x){
    if(S[x] != S[x].p){
        S[x].p = Find-Set(S[x].p);
    }
    return S[x].p;
}
void Union(x,y){
    Link(Find-Set(x),Find-Set(y));
}
void Link(x,y){
    if(x->rank > y->rank){
        y->p = x;
    }
    else{
        x->p = y;
        if(x->rank == y->rank){
            y->rank = y->rank +1;
        }
    }
}
时间: 2024-10-09 16:31:30

并查集:不相交集合的相关文章

并查集—分离集合森林实现

并查集总结 今天总结一下并查集,这个完了之后,寒假学的数据结构基础的模板类的题目差不多就完了,对于模板题,敲上10遍.20遍.30遍,那么模板就不是模板,就成为了你自己的东西,就好像 A+B 一辈子也忘不了,以后每天敲一遍模板题,加深对模板的理解. 并查集,一般使用的是 数组实现.树实现,其中数组实现时间复杂度较高,树实现也就是分离集合森林 查找.合并的时间复杂度不会 超过 O(log2n) n个人,m对有亲戚关系的 10 7 1 2 2 3 2 4 3 4 5 6 6 7 8 9 初始化:{1

BC68(HD5606) 并查集+求集合元素

tree Accepts: 143 Submissions: 807 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 有一个树(nn个点, n-1n−1条边的联通图),点标号从11~nn,树的边权是00或11.求离每个点最近的点个数(包括自己). 输入描述 第一行一个数字TT,表示TT组数据. 对于每组数据,第一行是一个nn,表示点个数,接下来n-1n−1,每行三个整数u,

并查集(集合合并) + 缩点

正解是dfs的一道题目被我以为成了并查集,结果坑了队友.现在分析一下自己当时为什么会想成是并查集呢. 题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2588 题意:告诉一张n点m边的图,求哪些边是桥.其实就是缩点,然而却大脑短路,直接认定是并查集了,现在的我真的不能理解当时的自己.... 当时想的是把所有的环缩成一个点,然后剩下的边就是桥了,缩点,第一时间想的就是并查集,其实并查集的操作一般有三个: 1.初始化 把

并查集 (Union-Find Sets)及其应用

定义 并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.常常在使用中以森林来表示. 集就是让每个元素构成一个单元素的集合,也就是按一定顺序将属于同一组的元素所在的集合合并. 主要操作 初始化 把每个点所在集合初始化为其自身. 通常来说,这个步骤在每次使用该数据结构时只需要执行一次,无论何种实现方式,时间复杂度均为O(N). 查找 查找元素所在的集合,即根节点. 合并 将两个元素所在的集合合并为一个集合. 通常来说,合并之前,应先判断两个元素是否属于

数据结构--并查集的原理及实现

一,并查集的介绍 并查集(Union/Find)从名字可以看出,主要涉及两种基本操作:合并和查找.这说明,初始时并查集中的元素是不相交的,经过一系列的基本操作(Union),最终合并成一个大的集合. 而在某次合并之后,有一种合理的需求:某两个元素是否已经处在同一个集合中了?因此就需要Find操作. 并查集是一种 不相交集合 的数据结构,设有一个动态集合S={s1,s2,s3,.....sn},每个集合通过一个代表来标识,该代表中集合中的某个元素. 比如,若某个元素 x 是否在集合 s1 中(Fi

poj1988 Cube Stacking(并查集

题目地址:http://poj.org/problem?id=1988 题意:共n个数,p个操作.输入p.有两个操作M和C.M x y表示把x所在的栈放到y所在的栈上(比如M 2 6:[2 4]放到[1 6]上为[2 4 1 6]),C x为输出x下面有几个数. 思路:并查集每个集合以栈最下面的数为根,维护两个数组num[x]表示x所在集合节点总数,count[x]表示x下方节点个数.每次查找压缩路径的时候更新count(换父节点的时候每轮都把父节点的count加给儿子,就可以一直更新到x所在栈

HDU 1213 How Many Tables (并查集)

How Many Tables Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 22498 Accepted Submission(s): 11193 Problem Description Today is Ignatius' birthday. He invites a lot of friends. Now it's dinner ti

数据结构学习笔记04树(堆 哈夫曼树 并查集)

一.堆(heap) 优先队列(Priority Queue):特殊的“队列”,取出元素的顺序是依照元素的优先权(关键字)大小,而不是元素进入队列的先后顺序. 数组 : 插入 — 元素总是插入尾部 ~ O ( 1 ) 删除 — 查找最大(或最小)关键字 ~ O ( n ) 从数组中删去需要移动元素 ~ O( n ) 链表: 插入 — 元素总是插入链表的头部 ~ O ( 1 ) 删除 — 查找最大(或最小)关键字 ~ O ( n ) 删去结点 ~ O( 1 ) 有序数组: 插入 — 找到合适的位置

HDU 3635-Dragon Balls(高级并查集)

Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3242    Accepted Submission(s): 1250 Problem Description Five hundred years later, the number of dragon balls will increase unexpect