并查集的初步认识

首先这个东西是解决什么问题的?什么情况下会用到?

很简单的例子,给出你一个数百万人关系网,随意挑选两个人,问你他们是否有联系?如何快速解决这类问题,这时候需要并查集

并查集意思是说,有个类似指针的东西,将子节点连接父节点,那么这个时候,父子节点是连接的,如果父节点是根节点,那么父节点的指针指向自己;这里让父节点为A,子节点为B,现在有个新节点C,要让C和B相连,我们只需要让C和B的根节点A相连就可以了;也就是说我们要判断连个点是否相连,只需要判断这两个点的根节点是否一致就行了

下面是代码实现(由于并查集在实现过程有许多优化比范围优化,层级优化,这里上的是优化之后的版本)

class data {
  constructor (count) {
     this.p = new Array(count)
     this.rank = new Array(count)
     for (let i = 0; i < count; i++) {
       this.p[i] = i
       this.rank[i] = 1 // 每个层级初始值为1
     }
  }
  find (target) {
    while (target != this.p[target]) {
      this.p[target] = this.p[this.p[target]]
      target = this.p[target]
    } // 递归找出根阶段
    return target
  }
  isconnect (one, two) {
    return this.find(one) === this.find(two)
  }
  union (one, two) {
    let Pone = this.find(one), Ptwo = this.find(two)
    if (Pone === Ptwo) {
      return
    }
    if (this.rank[Pone] < this.rank[Ptwo]) {
      this.p[Pone] = this.p[Ptwo]
    } else if (this.rank[Pone] > this.rank[Ptwo]) {
      this.p[Ptwo] = this.p[Pone]
    } else {
      this.p[Ptwo] = this.p[Pone]
      this.rank[Pone] += 1
    }

    return this.p
  }
}
时间: 2024-10-10 15:41:51

并查集的初步认识的相关文章

并查集(初步)

并查集可以查询某个是否在一个集合里,而且可以把两个或以上的集合合并起来. 比如有三个集合{1, 3, 5, 7, 9}, {2, 4, 6, 8, 10}, {11, 12, 13, 14},其中1和5在一个集合里2和11不在一个集合里. 经典的题目:n个人,有m对关系,如果a和b是亲戚,b和c是亲戚,则a和c也是亲戚,求有多少组亲戚.描述的不是很好,看例子吧.假设有5个人,1和2是亲戚,2和3是亲戚,4和5是亲戚.那么答案是2,因为亲戚组有两组,分别是{1, 2, 3},{4, 5}. 树关系

并查集初步题目(2)

vector和邻接表 并查集的一个很风骚的技巧 一. vector数组操作 包含vector头文件 声明:vector<type> name; 方法: 加入一个元素至最后:vec.push_back(val); 清空数组中的所有元素:vec.clear(); 访问其中元素:vec.at(i); vector中元素的个数:vec.size(); 指定当前vector内元素个数:vec.resize(n); 会保留前n个元素. 邻接表是一种储存图的方式,通常使用链表或者vector可变长数组实现.

并查集 (Union-Find Sets)及其应用

定义 并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.常常在使用中以森林来表示. 集就是让每个元素构成一个单元素的集合,也就是按一定顺序将属于同一组的元素所在的集合合并. 主要操作 初始化 把每个点所在集合初始化为其自身. 通常来说,这个步骤在每次使用该数据结构时只需要执行一次,无论何种实现方式,时间复杂度均为O(N). 查找 查找元素所在的集合,即根节点. 合并 将两个元素所在的集合合并为一个集合. 通常来说,合并之前,应先判断两个元素是否属于

并查集—分离集合森林实现

并查集总结 今天总结一下并查集,这个完了之后,寒假学的数据结构基础的模板类的题目差不多就完了,对于模板题,敲上10遍.20遍.30遍,那么模板就不是模板,就成为了你自己的东西,就好像 A+B 一辈子也忘不了,以后每天敲一遍模板题,加深对模板的理解. 并查集,一般使用的是 数组实现.树实现,其中数组实现时间复杂度较高,树实现也就是分离集合森林 查找.合并的时间复杂度不会 超过 O(log2n) n个人,m对有亲戚关系的 10 7 1 2 2 3 2 4 3 4 5 6 6 7 8 9 初始化:{1

The Suspects(并查集维护根节点信息)

The Suspects Time Limit: 1000MS   Memory Limit: 20000K Total Submissions: 37090   Accepted: 17980 Description Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. T

数据结构 之 并查集(Disjoint Set)

一.并查集的概念: 首先,为了引出并查集,先介绍几个概念: 1.等价关系(Equivalent Relation) 自反性.对称性.传递性. 如果a和b存在等价关系,记为a~b. 2.等价类: 一个元素a(a属于S)的等价类是S的一个子集,它包含所有与a有关系的元素.注意,等价类形成对S的一个划分:S的每一个成员恰好互斥地出现在一个等价类中.为了确定是否a~b,我们仅需验证a和b是否属于同一个等价类即可. 3.并查集: 即为等价类,同一等价类(并查集)中元素两两存在等价关系,不同并查集元素之间没

并查集算法的描述

1.概念: 在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中.这一类问题近几年来反复出现在信息学的国际国内赛题中,其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往在空间上过大,计算机无法承受:即使在空间上勉强通过,运行的时间复杂度也极高,根本就不可能在比赛规定的运行时间(1-3秒)内计算出试题需要的结果,只能用并查集来描述. 2.定义: 并查集是一种树型的数

CodeForces 745C Hongcow Builds A Nation 并查集

题意: 给了你n个城市 m条边 k个政府 每个政府管辖的区域内不能和其他政府的区域有相连 即政府之间不存在路径 问你在维护这种关系的同时 最多再加多少条边 思路: 先找出来每个联通块 再找出来没有归属的孤立的点 把他们都放到最大的联通块里 然后每个联通块之间的点两两连边是n*(n-1)/2条边 最后算出来的ans-m就好了 (看别人的博客学了一个max_element 1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a

并查集(个人模版)

并查集: 1 int find(int a) 2 { 3 int r=a; 4 while(f[r]!=r) 5 r=f[r]; 6 int i=a; 7 int j; 8 while(i!=r) 9 { 10 j=f[i]; 11 f[i]=r; 12 i=j; 13 } 14 return r; 15 } 16 int merge(int a,int b) 17 { 18 int A,B; 19 A=find(a); 20 B=find(b); 21 if(A!=B) 22 { 23 f[B