查集讲解(按秩合并与路径压缩)

自看。。。

借鉴自:https://blog.csdn.net/u011056504/article/details/51222494

1、路径压缩

void find(int x)
{
    return f[x] == x ? x : (f[x] = find(f[x]));
}

2、按秩合并

给每个点一个秩,其实就是树高 
每次合并的时候都用秩小的指向秩大的,可以保证树高最高为log2(n)log2(n) 
操作的时候,一开始所有点的秩都为1 
在一次合并后,假设是点x和点y,x的秩小 
当然x和y都是原来x和y所在区间的顶点 
设点x秩为rank[x] 
将fa[x]指向y,然后将rank[y]的与rank[x+1]取max 
因为rank[x]为区间x的高,将它连向y之后,y的树高就会是x的树高+1,当然也可能y在另一边树高更高,所以取max

程序

同样,fa[x]为x的父亲,就是x指向的点,rank[x]为点x的秩

//查询:
void find(int x)
{
    return f[x] == x ? x : find(f[x]);
}

//修改:

    int r = find(x);
    int l = find(y);
    if(r == l) continue;
    if(rank[l] <= rank[r]) f[l] = r, rank[r] = max(rank[r], rank[l] + 1);
    else f[r] = l, rank[l] = max(rank[l], rank[r] + 1);

原文地址:https://www.cnblogs.com/WTSRUVF/p/9416217.html

时间: 2024-09-28 12:06:17

查集讲解(按秩合并与路径压缩)的相关文章

并查集(2)-按秩合并和路径压缩

在上面一讲是并查集(1)-判断无向图是否存在环. 我们使用了并查集的两个操作: union() 和 find() // find 的原始实现 int find(int parent[], int i) { if (parent[i] == -1) return i; return find(parent, parent[i]); } // union()的原始实现 void Union(int parent[], int x, int y) { int xset = find(parent, x

[2017年第0届浙江工业大学之江学院程序设计竞赛决赛 I] qwb VS 去污棒(并查集,按秩合并,最小生成树,LCA)

题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=8 题意:中文题面. 手动画一下会发现所求边必然存在于最大生成树上,那么就可以首先构造一棵最大生成树. 问题转化成一棵树上求两个点之间的链上的最短边,用倍增lca就可以做了,但是我不会. 于是可以考虑建树时的操作,在求最大生成树的时候按秩合并,即集合大的根要做集合小的根的父亲,这样连一条有向边,保证路径上的所有边没有变化,并且能够维持整棵树高不会超过log(

并查集的按秩合并

表示吉利的讲课第一题我就听得一脸懵逼......没救啦 然后请教了一下伊嘉,大概明白了是对时间轴分治然后按秩合并,就回来学了下. POJ2492 传送门:http://poj.org/problem?id=2492 等等,我为什么要写这道题. 这道题,不用按秩也能A啊.... 15444012 wxx_louisa 2492 Accepted 192K 750MS C++ 784B 2016-04-27 19:26:42 15444008 wxx_louisa 2492 Accepted 200

普林斯顿公开课 算法1-10:并查集-优化的快速合并方法

应用 渗透问题 游戏中会用到. 动态连接 最近共同祖先 等价有限状态机 物理学Hoshen-Kopelman算法:就是对网格中的像素进行分块 Hinley-Milner多态类型推断 Kruskai最小生成树 Fortran等价语句编译 形态学开闭属性 Matlab中关于图像处理的bwlabel函数 渗透问题 一个N×N的矩阵,判断顶部和底部是否连通就是渗透问题. 下图中左侧的矩阵能渗透,右侧矩阵不能渗透. 渗透问题在电学.流体力学.社会交际中都有应用. 在游戏中可能需要生成一张地图,但是作为地图

并查集讲解(转)

并查集是我暑假从高手那里学到的一招,觉得真是太精妙的设计了.以前我无法解决的一类问题竟然可以用如此简单高效的方法搞定.不分享出来真是对不起party了.(party:我靠,关我嘛事啊?我跟你很熟么?) 来看一个实例,杭电1232畅通工程 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的.最后要解决的是整幅图的连通性问题.比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块.像畅通工程这题,问还需要修

并查集总结篇

1.模板题poj1611the suspects 每个组内的人,同一个组内都是感染者,问与"0"号人有关的有多少人 #include <iostream> #include<cstdio> using namespace std; const int MAXN = 1000100; struct DS { int f[MAXN]; void init(int n) { for(int i=0;i<n;i++) f[i]=i; } int ff(int x)

【经典数据结构】并查集

等价关系与等价类 若对于每一对元素(a,b),a,b∈S,a R b或者为true或者为false,则称在集合S上定义关系R.如果a R b为true,那么我们说a与b有关系. 等价关系(equivalence relation)是满足下列三个性质的关系R: (1) 自反性:对于所有a∈S,a R a (2) 对称性:若a R b当且仅当b R a (3) 传递性:若a R b且b R c 则a R c 关系“≤”不是等价关系.虽然它是自反的(即a≤a).可传递的(即由a≤b和b≤c得出a≤c)

poj2492 A Bug&#39;s Life (并查集拓展)

C - A Bug's Life Crawling in process... Crawling failed Time Limit:10000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2492 Appoint description: CSUST_11 (2013-04-14) System Crawler (2016-05-13) Description B

并查集(Disjoint Set)

http://www.cnblogs.com/cyjb/p/UnionFindSets.html http://blog.csdn.net/dm_vincent/article/details/7655764 http://blog.csdn.net/dm_vincent/article/details/7769159 并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有求连通子图.求最小生成树的 Kruskal 算法和