zoukankan      html  css  js  c++  java
  • 数据结构——并查集

    所谓并查集,顾名思义,是一个支持“并”,“查”的集合。

    并查集可以想象成一个森林,就是树的集合。

    在并查集中,还有一个重要思想:代元法。

    其实就是在每一个集合中选一个固定元素,作为集合的代表。

    有一种定义方法:用树形数据结构存储数据,树上的每一个节点都是一个元素,树根是代表元素。

    但一般来说,我们会维护一个fa数组,fa来保存父节点,根节点的fa是他自己。

    在我们初始化一个并查集时,元素的fa都是自己,然后才有get(查找)和merge(合并)操作。

    建并查集:

    1 int fa[10001];
    2 void init()
    3 {
    4     for(int i=1;i<=10001;i++)
    5         fa[i]=i;
    6 }

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                               路径压缩

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

    路径压缩 的思想是,我们只关心每个结点的父结点,而并不太关心树的真正的结构。这样我们在一次查询的时候,可以把查询路径上的所有结点的 father[i]father[i] 都赋值成为根结点。只需要在我们之前的查询函数上面进行很小的改动。

    比如说一棵存并查集的树

    这就是它的路径压缩,大大的减小了查询复杂度。

    接下来我们就来写Get,Merge的模板。

    查询(Get)

    1 int Get(int x)
    2 {
    3     if(fa[x]==x)//是树根就返回自己 
    4         return x;
    5     return fa[x]=Get(fa[x]);//递归查找父亲 
    6 }

    合并(Merge)

    1 void Merge(int x,int y)
    2 {
    3     fa[Get(x)]=Get(y);//x的树根变成y的树根 
    4 }

    其实除了并与查之外,还考一个操作:判断两个数是否属于同一集合。

    这个就直接用Get函数查找父亲是否相同就可以了。

    1 bool Judge(int x,int y)
    2 {
    3     int a=Get(x),y=Get(y);
    4     return a==b;
    5 }

    其实,这几个模板操作还很容易理解,重在多练,多想。

    之后我会再讲解一些习题,来帮助大家深入理解并查集。

    我们下次见!

  • 相关阅读:
    二分图匹配(匈牙利算法)
    最长共公子序列(LCS)
    网页常用Js代码
    linux 服务器常用命令整理
    阿里云学生服务器搭建网站-Ubuntu16.04安装php开发环境
    BAT批处理中的字符串处理详解(字符串截取)
    DOS批处理高级教程(还不错)(转)
    EntityFramework的linq扩展where
    RestSharp发送请求得到Json数据
    socket
  • 原文地址:https://www.cnblogs.com/sillyben/p/9925213.html
Copyright © 2011-2022 走看看