并查集 路径压缩

使用并查集查找时,如果查找次数很多,那么使用朴素版的查找方式肯定要超时。比如,有一百万个元素,每次都从第一百万个开始找,这样一次运算就是10^6,如果程序要求查找个一千万次,这样下来就是10^13,肯定要出问题的。

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

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

下面是采用路径压缩的方法查找元素:

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

上面是一采用递归的方式压缩路径, 但是,递归压缩路径可能会造成溢出栈,我曾经因为这个RE了n次,下面我们说一下非递归方式进行的路径压缩:

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

并查集 路径压缩的相关文章

hdu 1558 线段相交+并查集路径压缩

Segment set Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3457    Accepted Submission(s): 1290 Problem Description A segment and all segments which are connected with it compose a segment set.

poj 2513 Colored Sticks(欧拉回路 并查集 路径压缩 字典树)(困难)

Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 32545   Accepted: 8585 Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a st

并查集路径压缩与启发式合并

[程序清单] 初始化: for i:=1 to n do father[i]:=i; 因为每个元素属于单独的一个集合,所以每个元素以自己作为根结点. 寻找根结点编号并压缩路径: function getfather(v : integer) : integer; begin if father[v]=v then exit(v); father[v]:=getfather(father[v]); getfather:=father[v]; end; 合并两个集合: proceudre merge

HDU 3635 Dragon Balls(并查集--路径压缩拓展应用)

题目大意: 初始时,有n个龙珠,编号从1到n,分别对应的放在编号从1到n的城市中. 现在又2种操作: T A B,表示把A球所在城市全部的龙珠全部转移到B城市.(第一次时,因为A球所在的城市只有一个球,所以只移动1个,如果有多个,则全部移动). Q A,表示查询A.要求得到的信息分别是:A现在所在的城市,A所在城市的龙珠数目,A转移到该城市移动的次数(如果没有移动就输出0) 思路:并查集,难点在于求龙珠的转移次数,可以在路径压缩的过程中沿着递归路径累加. //Accepted 1740 KB 5

并查集 路径压缩(具体解释)

拿HDU 1232举例. 题解: 首先在地图上给你若干个城镇.这些城镇都能够看作点,然后告诉你哪些对城镇之间是有道路直接相连的.最后要解决的是整幅图的连通性问题.比方任意给你两个点,让你推断它们是否连通,或者问你整幅图一共同拥有几个连通分支,也就是被分成了几个互相独立的块.像畅通project这题,问还须要修几条路.实质就是求有几个连通分支.假设是1个连通分支,说明整幅图上的点都连起来了,不用再修路了.假设是2个连通分支,则仅仅要再修1条路,从两个分支中各选一个点,把它们连起来,那么全部的点都是

snnu(1110) 传输网络 (并查集+路径压缩+离线操作)

1110: 传输网络 Time Limit: 3 Sec  Memory Limit: 512 MBSubmit: 43  Solved: 18[Submit][Status][Web Board] [Edit] Description Byteland国家的网络单向传输系统可以被看成是以首都Bytetown为中心的有向树,一开始只有Bytetown建有基站,所有其他城市的信号都是从Bytetown传输过来的.现在他们开始在其他城市陆续建立了新的基站,命令“C x“代表在城市x建立了一个新的基站

并查集 路径压缩(详解)

拿HDU 1232举例. 题解: 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的.最后要解决的是整幅图的连通性问题.比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块.像畅通工程这题,问还需要修几条路,实质就是求有几个连通分支.如果是1个连通分支,说明整幅图上的点都连起来了,不用再修路了:如果是2个连通分支,则只要再修1条路,从两个分支中各选一个点,把它们连起来,那么所有的点都是连起来的了:如果

poj1988Cube Stacking(并查集+路径压缩)

本题依然是并查集的应用,与上一个监狱的问题不同,本题计算的是距离,通过记录通往自己父节点距离的相对距离,与父节点到根节点(代表元素)的距离依次相加 路径压缩时每次都要更新节点. #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int maxn=30001; int p; struct { int fat

poj1182食物链(带权并查集+路径压缩)

食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 60260   Accepted: 17665 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同