并查集的优化:按秩合并和路径压缩

转载 2016年08月31日 14:32:06

转载于:http://www.tuicool.com/articles/Zb2qYzj

并查集有两个优化。

一、按秩合并

描述:就是在对两个不同子集连接时,按照rank来连,也就是rank低的连在rank高的下面。rank高的做父亲节点。

作用,这样类似维护了一棵树,树是rank高的在上。

// 初始化n个元素
void init(int n)
{
    for(int i=0;i<n;i++)
    {
        parent[i]=i;
        rank[i]=0;   // 初始树的高度为0
    }
}


// 合并x和y所属的集合
void unite(int x,int y)
{
    x=find(x);
    y=find(y);
    if(x==y) return ;
    if(rank[x]<rank[y])
        parent[x]=y;  // 合并是从rank小的向rank大的连边
    else
    {
        parent[y]=x;
        if(rank[x]==rank[y]) rank[x]++;
    }
}

二、路径压缩

描述:假如fa数组已经嵌套了N层,那么传统的做法去找祖先要做N次,当N很大时,这种做法很没效率。

这是朴素查找的代码,适合数据量不大的情况

int findx(int x)
{
    int r=x;
   while(parent[r] !=r)
        r=parent[r];
   return r;
}

    下面是采用递归路径压缩的方法查找元素,但是,递归压缩路径可能会造成溢出栈会发生RE

int find(int x)       //查找x元素所在的集合,回溯时压缩路径
{
    if (x != parent[x])
    {
        parent[x] = find(parent[x]);     //回溯时的压缩路径
    }         //从x结点搜索到祖先结点所经过的结点都指向该祖先结点
    return parent[x];
}

下面我们说一下非递归方式进行的路径压缩

int find(int x)
{
    int k, j, r;
    r = x;
    while(r != parent[r])     //查找跟节点
        r = parent[r];      //找到跟节点,用r记录下
    k = x;        
    while(k != r)             //非递归路径压缩操作
    {
        j = parent[k];         //用j暂存parent[k]的父节点
        parent[k] = r;        //parent[x]指向跟节点
        k = j;                    //k移到父节点
    }
    return r;         //返回根节点的值            
}

并查集的两种优化(按秩合并,路径压缩)

并查集是建立在对不相交集合进行的两种基本操作的基础之上的。操作之一:检索某元素属于哪个集合;操作之二:合并两个集合。黑书上说了,这种结构显然可以用链表或森林实现,显然用链表进行查询时间复杂度应该是O(...
  • u010255534
  • u010255534
  • 2013年08月04日 22:14
  • 1442

并查集(按秩合并、路径压缩)

算法分类: 数据结构 算法原理: 通过find函数找出该节点的根节点, 通过UNION函数将两棵树合并。 加入rank[N]来记录每个节点的秩(即树的高度),并按秩进行合并,可避免合...
  • jokes000
  • jokes000
  • 2012年04月30日 11:15
  • 8618

UVA 11354 - Bond(并查集-按秩合并)

题目链接:点击打开链接 题意:给出一张n个点m条边的无向图, 每条边有一个危险度,有q个询问, 每次给出两个点s、t,找一条路, 使得路径上的最大危险度最小。 思路:首先,我们可以发现,如果求一个...
  • weizhuwyzc000
  • weizhuwyzc000
  • 2016年02月15日 16:14
  • 2178

POJ2524 并差集以及优化(路径压缩+按秩合并)的简洁介绍

0 题意很简单,略。 1 ①关于按秩合并中秩的一点说明,我理解的秩是集合的深度,大部分博客的代码与我的理解想同(即2-④ Join()中按秩合并代码中的秩就是严格代表着集合的深度),但是有的博客上: ...
  • a272846945
  • a272846945
  • 2016年07月29日 23:57
  • 254

并查集-按秩合并

1239: 中山学院 ACM小组 Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 79  Solved: 21 [Submit][Status][W...
  • qq_24489717
  • qq_24489717
  • 2015年06月16日 21:40
  • 1104

bzoj 4537: [Hnoi2016]最小公倍数 并查集按秩合并+分块

题意给出n个点m条边的无向图和q个询问,每条边有两个权值a和b,每个询问给出x y a b,问有没有一条x到y的路径(不一定是简单路径)满足max(e_a)==a且max(e_b==b) n,q...
  • qq_33229466
  • qq_33229466
  • 2017年03月14日 16:42
  • 198

并查集(两个优化—按秩合并、路径压缩) poj2492

并查集有两个优化。 一、按秩合并 描述:就是在对两个不同子集连接时,按照rank来连,也就是rank低的连在rank高的下面。rank高的做父亲节点。 作用,这样类似维护了一棵树,树是rank高...
  • u013694972
  • u013694972
  • 2014年04月20日 23:00
  • 1221

历史 (并查集 按秩合并)

历史(history.c/cpp/pas)题目描述 历史学家小A正在研究一个奇怪的王国的历史。当前阶段的任务是研究该国的交通。 根据这个奇怪的王国的史书记载,史书开始记载前这个王国有n个城市(城市...
  • w4149
  • w4149
  • 2017年08月28日 15:54
  • 276

并查集 按秩合并&路径压缩

并查集自己也只是会了方法,稍微有点思维难度的题就写不出来【例如银河英雄传说】,Menci教的代码。 还有Menci是把并查集写成了一个结构体,里面有各种成员函数,也超级棒。例题是HDU 1232#i...
  • lyx_2016
  • lyx_2016
  • 2016年10月31日 08:23
  • 545

【模版】并查集 及路径压缩

Ps:在网上看到的写的很好的并查集
  • u013486414
  • u013486414
  • 2014年08月19日 15:10
  • 5967
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:并查集的优化:按秩合并和路径压缩
举报原因:
原因补充:

(最多只允许输入30个字)