并查集

并查集算法(带你了解其原理 实现方法) 并查集算法是一种高效处理元素分组问题的数据结构,它通过维护一个父节点数组来实现元素的分组和合并操作。并查集算法在计算机科学中有广泛的应用,如判断无向图的连通性、判断有向图的强连通分量以及判断数组中的元素是否属于同一个子集等。通过采取一些优化措施,如路径压缩和按秩合并,可以进一步提高并查集算法的效率。 阅读详情

并查集 (Union-Find Sets)
并查集:(union-find sets)是一种简单的用途广泛的集合. 并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多。一般采取树形结构来存储并查集,并利用一个rank数组来存储集合的深度下界,在查找操作时进行路径压缩使后续的查找操作加速。这样优化实现的并查集,空间复杂度为O(N),建立一个集合的时间复杂度为O(1),N次合并M查找的时间复杂度为O(M Alpha(N)),这里Alpha是Ackerman函数的某个反函数,在很大的范围内(人类目前观测到的宇宙范围估算有10的80次方个原子,这小于前面所说的范围)这个函数的值可以看成是不大于4的,所以并查集的操作可以看作是线性的。它支持以下三中种操作:
  -Union (Root1, Root2) //并操作;把子集合Root2并入集合Root1中.要求:Root1和 Root2互不相交,否则不执行操作.
  -Find (x) //搜索操作;搜索单元素x所在的集合,并返回该集合的名字.
  -UFSets (s) //构造函数。将并查集中s个元素初始化为s个只有一个单元素的子集合.
  -对于并查集来说,每个集合用一棵树表示。
  -集合中每个元素的元素名分别存放在树的结点中,此外,树的每一个结点还有一个指向其双亲结点的指针。
  -设 S1= {0, 6, 7, 8 },S2= { 1, 4, 9 },S3= { 2, 3, 5 }

 


-为简化讨论,忽略实际的集合名,仅用表示集合的树的根来标识集合。
  -为此,采用树的双亲表示作为集合存储表示。集合元素的编号从0到 n-1。其中 n 是最大元素个数。在双亲表示中,第 i 个数组元素代表包含集合元素 i 的树结点。根结点的双亲为-1,表示集合中的元素个数。为了区别双亲指针信息( ≥ 0 ),集合元素个数信息用负数表示。   

下标
parent
 
 

集合S1, S2和S3的双亲表示:


                             S1 ∪ S2的可能的表示方法

const int DefaultSize = 10;
  class UFSets { //并查集的类定义
  private:
   int *parent;
   int size;
  public:
   UFSets ( int s = DefaultSize );
   ~UFSets ( ) { delete [ ] parent; }
   UFSets & operator = ( UFSets const & Value );//集合赋值
   void Union ( int Root1, int Root2 );
   int Find ( int x );
   void UnionByHeight ( int Root1, int Root2 ); };
   UFSets::UFSets ( int s ) { //构造函数
   size = s;
   parent = new int [size+1];
   for ( int i = 0; i <= size; i++ ) parent[i] = -1;
  }

  unsigned int UFSets::Find ( int x ) { //搜索操作
   if ( parent[x] <= 0 ) return x;
   else return Find ( parent[x] );
  }

  void UFSets::Union ( int Root1, int Root2 ) { //并
   parent[Root2] = Root1; //Root2指向Root1
  }

Find和Union操作性能不好。假设最初 n 个元素构成 n 棵树组成的森林,parent[i] = -1。做处理Union(0, 1), Union(1, 2), …, Union(n-2, n-1)后,将产生如图所示的退化的树。

                            


执行一次Union操作所需时间是O(1),n-1次Union操作所需时间是O(n)。若再执行Find(0), Find(1), …, Find(n-1), 若被
搜索的元素为i,完成Find(i)操作需要时间为O(i),完成 n 次搜索需要的总时间将达到
              

Union操作的加权规则

  为避免产生退化的树,改进方法是先判断两集合中元素的个数,如果以 i 为根的树中的结点个数少于以 j 为根的树中的结点个数,即parent[i] > parent[j],则让 j 成为 i 的双亲,否则,让i成为j的双亲。此即Union的加权规则。

              parent[0](== -4) < parent[4] (== -3)

 

  void UFSets::WeightedUnion(int Root1, int Root2) {
   //按Union的加权规则改进的算法
   int temp = parent[Root1] + parent[Root2];
   if ( parent[Root2] < parent[Root1] ) {
    parent[Root1] = Root2; //Root2中结点数多
    parent[Root2] = temp;  //Root1指向Root2
   }
   else {
    parent[Root2] = Root1; //Root1中结点数多
    parent[Root1] = temp;  //Root2指向Root1
   }
  }

 


                            使用加权规则得到的树

 

下面是几到用并查集可以方便解决的问题:

 

题目: 亲戚(Relations)

或许你并不知道,你的某个朋友是你的亲戚。他可能是你的曾祖父的外公的女婿的外甥的表姐的孙子。如果能得到完整的家谱,判断两个人是否亲戚应该是可行的,但如果两个人的最近公共祖先与他们相隔好几代,使得家谱十分庞大,那么检验亲戚关系实非人力所能及.在这种情况下,最好的帮手就是计算机。

为了将问题简化,你将得到一些亲戚关系的信息,如同Marry和Tom是亲戚,Tom和B en是亲戚,等等。从这些信息中,你可以推出Marry和Ben是亲戚。请写一个程序,对于我们的关心的亲戚关系的提问,以最快的速度给出答案。

参考输入输出格式 输入由两部分组成。

第一部分以N,M开始。N为问题涉及的人的个数(1 ≤ N ≤ 20000)。这些人的编号为1,2,3,…,N。下面有M行(1 ≤ M ≤ 1000000),每行有两个数ai, bi,表示已知ai和bi是亲戚.

第二部分以Q开始。以下Q行有Q个询问(1 ≤ Q ≤ 1 000 000),每行为ci, di,表示询问ci和di是否为亲戚。

对于每个询问ci, di,若ci和di为亲戚,则输出Yes,否则输出No。

样例输入与输出

输入relation.in

10 7

2 4

5 7

1 3

8 9

1 2

5 6

2 3

3

3 4

7 10

8 9

输出relation.out

Yes

No

Yes

如果这道题目不用并查集,而只用链表或数组来存储集合,那么效率很低,肯定超时。

例程:

 

#include<iostream>

using namespace std;

int N,M,Q;

int pre[20000],rank[20000];

void makeset(int x)

 {

     pre[x]=-1;

     rank[x]=0;

 }

int find(int x)

 {

     int r=x;

     while(pre[r]!=-1)

      r=pre[r];

     while(x!=r)

      {

          int q=pre[x];

          pre[x]=r;

          x=q;

      }

    return r;      

 }    

void unionone(int a,int b)

 {

     int t1=find(a);

     int t2=find(b);

     if(rank[t1]>rank[t2])

       pre[t2]=t1;

    else

       pre[t1]=t2;

    if(rank[t1]==rank[t2])

      rank[t2]++;     

 }       

int main()

 

{

   int i,a,b,c,d;

    while(cin>>N>>M)

     {

         for(i=1;i<=N;i++)

          makeset(i);

        for(i=1;i<=M;i++)

          {

              cin>>a>>b;

              if(find(a)!=find(b))

               unionone(a,b);

          }

        cin>>Q; 

        for(i=1;i<=Q;i++)

         {

             cin>>c>>d;

             if(find(c)==find(d))

              cout<<"YES"<<endl;

             else

              cout<<"NO"<<endl; 

         }           

     }   

    return 0;

}

 

ZJU1789The Suspects

【问题描述】

 

Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. To minimize transmission to others, the best strategy is to separate the suspects from others.

In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups. Students in the same group intercommunicate with each other frequently, and a student may join several groups. To prevent the possible transmissions of SARS, the NSYSU collects the member lists of all student groups, and makes the following rule in their standard operation procedure (SOP).

Once a member in a group is a suspect, all members in the group are suspects.

However, they find that it is not easy to identify all the suspects when a student is recognized as a suspect. Your job is to write a program which finds all the suspects.


Input

The input contains several cases. Each test case begins with two integers n and m in a line, where n is the number of students, and m is the number of groups. You may assume that 0 < n <= 30000 and 0 <= m <= 500. Every student is numbered by a unique integer between 0 and n-1, and initially student 0 is recognized as a suspect in all the cases. This line is followed by m member lists of the groups, one line per group. Each line begins with an integer k by itself representing the number of members in the group. Following the number of members, there are k integers representing the students in this group. All the integers in a line are separated by at least one space.

A case with n = 0 and m = 0 indicates the end of the input, and need not be processed.


Output

For each case, output the number of suspects in one line.


Sample Input

100 4
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2
200 2
1 5
5 1 2 3 4 5
1 0
0 0


Sample Output

4
1
1

【算法分析】

 

这道题的意思很简单,n个人编号,从0到n-1,这n个人分成m个集合(1个人可以参加不同的集合),求的就是最后所有和0号有关系的集合的

人数.

如果这道题目不用并查集,而只用链表或数组来存储集合,那么效率很低,肯定超时.我们在题目给出的每个集合的人员编号时,进行并查

操作,不过在进行合并操作时,合并的是两个集合的元素个数.最后0号元素所在的集合数目就是所求.

例程:

#include<iostream>

#include<cstdio>

using namespace std;

const int size=30000;

int pre[size],num[size];

int n,m,k;

void makeset(int x)

 {

     pre[x]=-1;

     num[x]=1;

 }

int find(int x)//非递归压缩路径

 {

     int r=x;

     while(pre[r]!=-1)

      r=pre[r];

     while(x!=r)

      {

          int q=pre[x];

          pre[x]=r;

          x=q;

      }

    return r;      

 }    

int unionone(int a,int b)

{

    int t1,t2;

    t1=find(a);

    t2=find(b);

    if(t1==t2) return 0;

    if(num[t2]<=num[t1])

    {

        pre[t2]=t1;

        num[t1]+=num[t2];

    }

    else

    {

        pre[t1]=t2;

        num[t2]+=num[t1];

    }

    return 0;

}

int main()

 {  

     freopen("in.txt","r",stdin);

     freopen("out.txt","w",stdout);

     int i,j,a,b;

     while(scanf("%d%d",&n,&m))

      {

          if(n==0&&m==0)

           break;

          for(i=0;i<n;i++)

            makeset(i);

          for(i=0;i<m;i++)

           {

               //cin>>k;

               scanf("%d",&k);

               if(k==0) continue;

               //cin>>a;

                scanf("%d",&a);

                a=find(a);

               for(j=1;j<k;j++)

                {

                    //cin>>b;

                    scanf("%d",&b);

                    b=find(b);

                    unionone(a,b);

                }   

           }

         printf("%d/n",num[find(0)]);      

      }   

     return 0;

 }    

 

  

   

    

     

       

 

 

银河英雄传说

 

【问题描述】

        公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展。

        宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争。泰山压顶集团派宇宙舰队司令莱因哈特率领十万余艘战舰出征,气吞山河集团点名将杨威利组织麾下三万艘战舰迎敌。

        杨威利擅长排兵布阵,巧妙运用各种战术屡次以少胜多,难免恣生骄气。在这次决战中,他将巴米利恩星域战场划分成30000列,每列依次编号为1, 2, …, 30000。之后,他把自己的战舰也依次编号为1, 2, …, 30000,让第i号战舰处于第i列(i = 1, 2, …, 30000),形成“一字长蛇阵”,诱敌深入。这是初始阵形。当进犯之敌到达时,杨威利会多次发布合并指令,将大部分战舰集中在某几列上,实施密集攻击。合并指令为M i j,含义为让第i号战舰所在的整个战舰队列,作为一个整体(头在前尾在后)接至第j号战舰所在的战舰队列的尾部。显然战舰队列是由处于同一列的一个或多个战舰组成的。合并指令的执行结果会使队列增大。

        然而,老谋深算的莱因哈特早已在战略上取得了主动。在交战中,他可以通过庞大的情报网络随时监听杨威利的舰队调动指令。

        在杨威利发布指令调动舰队的同时,莱因哈特为了及时了解当前杨威利的战舰分布情况,也会发出一些询问指令:C i j。该指令意思是,询问电脑,杨威利的第i号战舰与第j号战舰当前是否在同一列中,如果在同一列中,那么它们之间布置有多少战舰。

        作为一个资深的高级程序设计员,你被要求编写程序分析杨威利的指令,以及回答莱因哈特的询问。

        最终的决战已经展开,银河的历史又翻过了一页……

 

【输入文件】

输入文件galaxy.in的第一行有一个整数T(1<=T<=500,000),表示总共有T条指令。

以下有T行,每行有一条指令。指令有两种格式:

1.        M  i  j  :i和j是两个整数(1<=i , j<=30000),表示指令涉及的战舰编号。该指令是莱因哈特窃听到的杨威利发布的舰队调动指令,并且保证第i号战舰与第j号战舰不在同一列。

2.        C  i  j  :i和j是两个整数(1<=i , j<=30000),表示指令涉及的战舰编号。该指令是莱因哈特发布的询问指令。

 

【输出文件】

输出文件为galaxy.out。你的程序应当依次对输入的每一条指令进行分析和处理:

如果是杨威利发布的舰队调动指令,则表示舰队排列发生了变化,你的程序要注意到这一点,但是不要输出任何信息;

 如果是莱因哈特发布的询问指令,你的程序要输出一行,仅包含一个整数,表示在同一列上,第i号战舰与第j号战舰之间布置的战舰数目。如果第i号战舰与第j号战舰当前不在同一列上,则输出-1。

 

【样例输入】

4

M 2 3

C 1 2

M 2 4

C 4 2

 

【样例输出】

-1

1

 

【样例说明】

战舰位置图:表格中阿拉伯数字表示战舰编号

 
 第一列
 第二列
 第三列
 第四列
 ……
 
初始时
 1
 2
 3
 4
 ……
 
M 2 3
 1
 
 3

2
 4
 ……
 
C 1 2
 1号战舰与2号战舰不在同一列,因此输出-1
 
M 2 4
 1
 
 
 4

3

2
 ……
 
C 4 2
 4号战舰与2号战舰之间仅布置了一艘战舰,编号为3,输出1
 

 

【算法分析】

        同一列的战舰组成一个并查集,在集合中,我们以当前列的第一艘战舰作为集合的代表元.并查集的数据类型采用树型,树的根结点即为集合的代表元.为了查询的效率达到最优,我们进行了路径压缩的优化:首先找到树根,然后将路径上所有结点的父结点改为根,使得树的深度为1.

        问题是,题目不仅要求判别两个结点是否在同一个集合(即两艘战舰是否在同一列),而且还要求计算结点在有序集合的位置(即每一艘战舰相隔列的第一艘战舰几个位置),       我们增加了一个数组behind[x],记录战舰x在例中的相对位置.

        查找一个元素x所在集合的代表元时,先从x沿着父亲节点找到这个集合的代表元root,然后再从x开始一次到root的遍历,累计其间经过的每一个子结点的behind值,其和即为behind[i].,如下图所示:

          


       按照题意,合并指令Mxy,含义是让战舰x 所在的整个战舰队列,作为一个整体(头在前,尾在后)接至战舰y所在的战舰队列的尾部,显然两个队列合并成同一列后,其集合代表元为结点y所在的树的根结点fy,x所在的树的根结点fx,合并后,fx的相对位置为合并前y所在集合的结点数, behind[fx]=num[fy],新集合的结点数为原来两个集合结点数的和 num[fy]+=num[fx]. 则如果战舰x和战舰y在同一列,则他们相隔

|behind[x]-behind[y]|-1艘战舰.如下图:

 

 


例程:

#include<iostream>

#include<cstdio>

#include<cmath>

using namespace std;

const int size=30001;

int pre[size],num[size],behind[size];//behind[x]战舰x在列中的相对位置

int n,m,k;

void makeset(int x)

 {

     pre[x]=-1;

     num[x]=1;

 }

int find(int x)//查找结点x所在树的根结点,并对该树进行路径压缩

 {

     int r=x;

     int j;

     while(pre[r]!=-1)//找出结点x所在树的根结点r

      r=pre[r];

     while(x!=r)

      {

          int q=pre[x];//路径压缩

          pre[x]=r;

          j=q;

          do{//迭代求出路径上每一个子结点相对于r的相对位置

              behind[x]+=behind[j];

              j=pre[j];

            }while (j!=-1);   

          x=q;

      }

    return r;      

 }    

void MoveShip(int a,int b)

{

    int t1,t2;

    t1=find(a);//计算a所在树的根结点t1

    t2=find(b);//计算b所在树的根结点t2

    pre[t1]=t2;//将t1的父结点设为t2

    behind[t1]=num[t2];//计算t1的相对位置为num[t2]

    num[t2]+=num[t1]; //计算新集合的结点数

 

}

 

void CheckShip(int x,int y)

 {

     int f1,f2;

     f1=find(x);

     f2=find(y);

     if(f1!=f2)

      cout<<-1<<endl;

     else

      cout<<abs(behind[x]-behind[y])-1<<endl;

 }

int main()

 {

   freopen("galaxy.in","r",stdin);

    freopen("out.txt","w",stdout);

 

     int n,x,y;

     char ch;

     while(cin>>n)

      {

          for(int i=1;i<size;i++)

           {

               makeset(i);

           }

          memset(behind,0,sizeof(behind));   

          while(n--)

           {

               cin>>ch>>x>>y;

               if(ch=='M')

                 MoveShip(x,y); //处理合并指令

               else if(ch=='C')

                 CheckShip(x,y);  //处理询问指令

           }   

      } 

   return 0;    

 }

 

并查集(标准并查集、带权并查集、扩展域并查集) 并查集是一种数据结构,用来管理集合之间的关系,可以用来进行判断是否属于同一集合或将不同的集合合并等操作。我们用个生活中的例子来说明一下原本小明家这个集合只有小明,小红家只有小红,那么他们结婚后(合并)就属于一个家庭(一个集合),像这样,通过并查集我们能够合并不同的集合,然后还能快速地查找他们是不是同一个集合。 阅读详情

相关推荐

C++ 并查集算法

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

struct_GS的博客 5250

数据结构--并查集

并查集

信息学奥赛学案 1561

扩展域并查集 & 带权并查集

扩展域并查集通过拆分域来表示复杂关系,逻辑直观且易于理解。虽然空间开销较大,但在处理复杂关系问题时非常高效。带权并查集通过维护权值来表示节点之间的关系,路径压缩和权值更新确保了高效的关系推导。虽然逻辑稍复杂,但代码简洁且高效,适合处理类似食物链的问题。

Lostgreen的博客 1870

并查集详解(原理+代码实现+应用+优化)

数据结构并查集详解

m0_70980326的博客 3945

并查集及带权并查集

若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系。xxx和yyy是亲戚,yyy和zzz是亲戚,那么xxx和zzz也是亲戚。如果xxxyyy是亲戚,那么xxx的亲戚都是yyy的亲戚,yyy的亲戚也都是xxx的亲戚。带权并查集是一种用于解决带权无向图中连通性问题的数据结构。它是并查集的扩展,包括点带权和边带权。它除了记录元素之间的关系外,还可以记录元素的权重。在点带权中,我们使用n。

bhdwyl的博客 1004

当vCenter的证书过期、Root密码过期、Root密码遗忘同时发生时的解决方法与步骤

vCenter,强制修改root密码,修改SSO User密码,修复证书过期问题

OCTSJimmy的专栏 5549

算法学习笔记——数据结构:并查集Union-find Set

并查集(UnionFindSet) 并查集(UnionFindSet)用于维护多个集合之间的关系,其名称显示了其功能,它提供了三个API: 合并:合并两个集合(只需从不同集合中分别给出两个元素即可) 查找:查看两元素是否属于同一集合 集合:维护多个集合的关系,查询当前有多少个独立的集合 并查集常可应用与图的有关问题,因为它与图中连通分量的概念相关:例如在遍历树/图的过程中,需要不断将两个不同的连通分量连接合并在一起,最后求一共有几个连通分量/求两元素是否属于同一连通分量等 并查集的实现 并查集的核心

Insomnia_X的博客 750

【gridsample】地平线征程6芯片中gridsample算子的优化与部署实践

本文详细介绍了地平线征程6芯片中gridsample算子的优化与部署实践,重点探讨了PTQ和QAT量化方案在BEV感知任务中的应用。通过双线性插值优化、内存布局调整和混合精度配置等关键技术,显著提升了算子在自动驾驶场景下的性能和精度,为开发者提供了实用的部署指南和调优建议。

zero1的博客 1019

算法与数据结构——并查集、种类并查集和带权并查集

并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。并查集的思想是用一个数组表示了整片森林(parent),树的根节点唯一标识了一个集合,我们只要找到了某个元素的的树根,就能确定它在哪个集合里。

qq_56639722的博客 3079

组合导航、惯导、GNSS、INS、IMU的区别

‌:惯性导航系统(INS)是一种利用安装在运载体上的陀螺仪和加速度计来测定运载体位置的系统。它通过测量物体的加速度和角速度,结合算法计算出物体的位置、速度和姿态‌12。‌。

wynn1123的博客 8054

保姆级教程:用Vue3+Element Plus快速搭建Flowable流程定义管理后台界面

本文提供了一份详细的Vue3+Element Plus教程,指导开发者快速搭建Flowable流程定义管理后台界面。从项目初始化、核心页面设计到响应式数据处理,全面覆盖前端开发关键步骤,帮助提升企业级应用开发效率。

weixin_42662293的博客 480

带权并查集 & 种类并查集

带权并查集就是在维护集合关系的树中添加边权的并查集,这样做可以维护更多的信息。 在对并查集进行路径压缩和合并操作时,这些权值具有一定属性,即可将他们与父节点的关系,变化为与所在树的根结点关系。 也就是说,权值代表着**当前节点与父节点的某种关系(即使路径压缩了也是这样)**,通过两者关系,一般的并查集,维护的是具有连通性、传递性的关系,例如**亲戚的亲戚是亲戚**。但是,有时候,我们要维护另一种关系:**敌人的敌人是朋友**。种类并查集就是为了解决这个问题而也可以将同一棵树下两个节点的关系表示出来。

SZTU_ZJB的博客 1991

CAD制图

CAD制图可以提高设计效率和准确性,并方便文档的存档和交流,是现代工程设计中不可或缺的一部分。·CAD三维开发是指使用计算机程序和工具来创建、编辑和操作三维模型、图形和设计的过程。它在工程、建筑、制造和游戏等领域广泛应用。CAD三维开发可能涉及到复杂的图形算法、性能优化、并行计算等方面的内容,因此需要深入学习和实践,以提高开发的效率和质量。

RZer的博客 1652

并查集,扩展域并查集,带边权并查集详解,OJ练习,详细代码

一看就会系列

EQUINOX1的博客 2868

全网最详细 解决戴维南定理的详细推导

替代定理,戴维南定理详细证明

m0_52555753的博客 3万+

从Protocol到硬件控制:揭秘高通UEFI中ABL与XBL的协作机制

本文深入解析了高通UEFI架构中ABL与XBL的协作机制,重点探讨了Protocol通信在硬件控制中的关键作用。通过对比传统GPIO控制方式,揭示了Protocol架构在安全性、可维护性和灵活性方面的优势,并提供了关机充电场景的实战案例分析及调试技巧。

weixin_29185199的博客 431

并查集和带权并查集及分类并查集

并查集是一种集并集查询于一体的数据结构,它的时间复杂度是Oαn)),阿尔法函数是阿克曼函数的反函数,返回值一般不超过3,数很大时一般不超过7,因此并查集的均摊时间复杂度接近O(1)。一般用来判断两个点是否相通,也可以用来判环,当相通的两个点连接时就会出现环,环的长度是两个点分别到根结点的路径之和加一。

gaomuchen_120309的博客 1044

激光雷达与相机时间戳同步:原理、触发方案与工程实现

目录一、引言:时间不同步,多传感器融合必出问题二、核心原理:相机成像机制与触发模式(同步的基础)2.1 相机成像的两个核心阶段:曝光与读出(1)非交叠曝光(2)交叠曝光2.2 相机触发模式:内触发 vs 外触发(1)内触发(2)外触发2.3 关键信号:Strobe信号与预输出(同步的核心技巧)三、三种主流时间戳同步方案(工程落地首选)3.1 方案一:统一硬触发(精度最高,高端场景首选)核心原理核心配置要点优缺点适用场景3.2 方案二:软触发+硬触发(Strobe预输出,车载量产首选)核心原理核心配置要点优缺

getusushu的博客 201

数据结构:并查集,种类并查集,带权并查集

最近学了并查集,写篇博客巩固一下~有时候,我们并不关心数据之间的前后关系,也不关心数据的层次关系。一些确定元素只是单纯的聚集在一起,这样的元素聚集体被称为集合。当希望知道某个数据是否存在一个集合中,或者两个元素是否在同一个集合中时,就需要使用一些集合数据结构来维护集合元素之间的关系。而并查集就是一个维护集合的数据结构。

ffqws_的博客 1173

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

浅谈并查集

一些简单种类的并查集

qq_43052183的博客 1219

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

种类并查集(并查集难点)

种类并查集概念例题 概念 一.什么是种类并查集? 顾名思义就是把一个集合中的元素根据他们不同的关系进行分类与合并。朋友的朋友就是朋友(普通并查集) ,但敌人的敌人也是朋友(维护这种关系就是种类并查集了)。例如:有一伙人他们要拔河(分成两个队),如果小a与小b是敌对关系,那么就不能在一个队,如果小a与小c是朋友,那么他们就在一个队;(朋友的朋友就是朋友,敌人的敌人也是朋友。 ) 种类并查集的作用就是不让两个有敌对关系的人在同一个队伍 二.种类并查集的应用 把朋友放在同一集合里,把敌人放另一集合里。放一起会打架

qq_47549346的博客 4360

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

【并查集】 带权并查集详解

一.引入 并查集实际上是一颗由若干个树构成的森林,而如果还需要储存边的权值,则需要额外用一个数组d记录每个结点和其父节点的权值 这个思路其实很简单,但是因为路径压缩会改变点与点的连接关系,路径压缩后,点的父节点变为了根节点,所以需要更新d数组 二.查询函数写法 更新权值在查询操作的同时进行 int root_find(int x){ if(x==pre[x]) return x; int root=root_find(pre[x]); d[x]+=d[pre[...

Qiuker_jl的博客 2488

并查集进阶

并查集进阶 文章目录并查集进阶绪论普通并查集初始化搜索合并带权并查集初始化搜索合并种类并查集例题HDU3047(种类并查集)HDU3635(带权并查集)POJ1988(带权并查集)POJ2912(种类并查集)POJ1456(普通并查集) 绪论 我本来以为并查集是一种很简单的数据结构,但是实在是被kuangbin的专题虐的死去活来,故在此总结一下 并查集目前有三部分: 普通并查集,带权并查集,种类并...

Dawn-K の Blog 859
上一篇: Prim算法实现(详细伪码)
下一篇: 更高效率的a^b mod c
cclsoft
博客等级 码龄19年 39粉丝 113原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值