首页 > 其他分享 >并查集

并查集

时间:2022-09-03 19:26:53浏览次数:77  
标签:merge int 查集 fa find size

并查集,是用代表元素来维护一个集合的数据结构。可以差不多\(O(1)\)地查询两个元素是否在同一个集合内。

并查集主要通过路径压缩和按秩合并减小复杂度。单独用的话最坏复杂度都是\(O(logn)\)的(虽然只路径压缩的均摊复杂度还是差不多\(O(1)\))。分开讲。

首先是初始化,每个元素各自属于自己的集合。

for(int i=1;i<=n;i++)fa[i]=i;
  1. 路径压缩

我们发现,一个点无论是与它的代表节点相连还是与别的什么节点相连对最后的结果是没有影响的。也就是说,我们可以每次查询的时候把这个节点连到代表节点上,即路径压缩。

int find(int x){
    if(fa[x]!=x)fa[x]=find(fa[x]);//路径压缩
    return fa[x];
}
  1. 按秩合并

资料里对这个秩的定义大概有两种:深度和集合大小。一般按照集合大小,即启发式合并。具体地说,小的扔到大的上。

void merge(int x,int y){
    x=find(x);y=find(y);
    if(size[x]<size[y])fa[x]=y;//x比较小 连到y上(其实一般不要这个) 
    else fa[y]=x;
}

然后是两个小应用。

  1. 边带权

P1196 [NOI2002] 银河英雄传说

这个题要求两点间的距离。显然这个可以转成到最头上的点的距离,也就是并查集的代表元素。使用并查集。

求距离时我们使每条边带1的边权。具体地,我们把上边两个东西稍微改一下。

int find(int x){
    if(fa[x]==x)return x;
    int rt=find(fa[x]);
    dis[x]+=dis[fa[x]];//路径压缩时 fa[x]已经存储了到根节点的距离 直接加上就行 
    fa[x]=rt;return fa[x];
}
void merge(int x,int y){
    x=find(x);y=find(y);
    fa[x]=y;dis[x]+=size[y];
	size[y]+=size[x];size[x]=0;
}
  1. 扩展域

P2024 [NOI2001] 食物链

这个题要维护三种关系:同类,天敌,食物。

我们可以开三倍大小的并查集,分别维护这三种关系。

当回答到x,y是同类时,x的同类与y的同类合并,x的食物与y的食物合并,x的天敌与y的天敌合并。

当回答到x吃y时,x的食物与y的同类合并,x的天敌与y的食物合并,x的同类与y的天敌合并。

void solve(int a){
	if(a==1){
		if(find(b+n)==find(c)||find(b+2*n)==find(c)){cnt++;continue;}
		merge(b,c);merge(b+n,c+n);merge(b+2*n,c+2*n);
	}
	if(a==2){
		if(b==c){cnt++;continue;}
		if(find(b)==find(c)||find(b+2*n)==find(c)){cnt++;continue;}
		merge(b,c+2*n);merge(b+n,c);merge(b+2*n,c+n);
	}
}

标签:merge,int,查集,fa,find,size
From: https://www.cnblogs.com/gtm1514/p/16653355.html

相关文章

  • 【数据结构】并查集(1) 萌新的并查集学习之路
    最基本的并查集:维护n个元素间的相关关系并查集的初始化为将n个元素各自看成一个集合,并通过不断的合并命令(将两个集合的根节点指向同一处)和查找命令(查找两个集合的根节点是......
  • [Google] LeetCode 1101 The Earliest Moment When Everyone Become Friends 并查集
    Therearenpeopleinasocialgrouplabeledfrom0ton-1.Youaregivenanarraylogswherelogs[i]=[timestampi,xi,yi]indicatesthatxiandyiwillbe......
  • 并查集
    https://leetcode.cn/problems/number-of-islands/给你一个由 '1'(陆地)和'0'(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方......
  • 算法提高课 第四章 数据结构之并查集
    一、并查集1250.格子游戏思路O(mlog(n))将图中的每个点看作并查集的结点,每个被画的边看作合并相邻的点的操作将图中所有点按行或列优先,从1~n*m进行编号每次进行......
  • 模拟赛 d (扫描线,三维偏序,线段树合并,并查集,线段树上二分)
    PRO题目大意:给定$N$个矩形,求连通块个数。($1\leqN,x_1,x_2,y-1,y_2\leq100000$)SOL乍一看就能知道是扫描线,不过这题的细节恐怖的要命。(std同样看不懂,自己魔改了一......
  • 种类并查集 把find变成查索引 unity变成x是y的
    真假英雄http://oj.saikr.com/contest/20/problem/K在一个小镇上,很多人都患了一个精神病,他们都认为自己是“英雄”或者“反派”中间的一种,“英雄”觉得自己是正义的一方,......
  • 1039 银河英雄传说 并查集实现蜘蛛卡牌 有bug
     链接:https://ac.nowcoder.com/acm/contest/26077/1039来源:牛客网题目描述  公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表......
  • 并查集(dsu)
    一共有n个数,编号是1∼n,最开始每个数各自在一个集合中。现在要进行m个操作,操作共有两种:Mab,将编号为a和b的两个数所在的集合合并,如果两个数已经在同一个集......
  • 并查集模板
    Python版本classUF:parent={}size={}cnt=0def__init__(self,M):#初始化parent,size和cnt#self.parent={ifori......
  • luoguP3224 [HNOI2012]永无乡【线段树,并查集】
    洞庭青草,近中秋,更无一点风色。玉鉴琼田三万顷,着我扁舟一叶。素月分辉,明河共影,表里俱澄澈。悠然心会,妙处难与君说。应念岭表经年,孤光自照,肝胆皆冰雪。短发萧骚襟袖冷,稳泛......