并查集的应用(一)

  • Post author:
  • Post category:其他







一 理论知识


1  定义:

并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)



的合并及查询问题。


2  主要操作:




初始化:


把每个点所在集合初始化为其自身。


通常来说,这个步骤在每次



使用该数据结构时只需要一次,无论何种实现方式,



时间复杂度


均为 O(N)。



查找:


查找元素所在的集合,即根节点。




合并:


将两个元素所在的集合合并为一个集合。



3  简单实现:


int par[MAX_N], rank[MAX_N];  
        //加了一个rank数组记录树的高度 
	//避免像二叉搜索树退化成单链表 
	//注意在题目数据过大时,可以不   
	//记录树的高度,否则会超时。
void Init(int n){
    int i;
    for(i=0; i<n; i++){
      par[i]=i;
      rank[i]=0;
    }
}

int Find(int x){    //注意体会在递归的过程中进行路径压缩
  if(x!=par[x])
         par[x]=Find(par[x]);  
  return par[x];
}


void unite(int x, int y){
   x=Find(x);
   y=Find(y);

  if(x==y)  return;

   if(rank[x]<rank[y]){
      par[x]=y;
   }
   else{
      par[y]=x;
      if(rank[x]==rank[y])
        rank[x]++;
   }
}


二  简单应用


1. 家族关系(最简单的应用)


描述

若某个家族人员过于庞大,要判断两个是否是亲戚,确实


还很不容易,现在给出某个亲戚关系图,求任意给出的两个人


是否具有亲戚关系。 规定:x和y是亲戚,y和z是亲戚,那么x


和z也是亲戚。如果x,y是亲戚,那么x的亲戚 都是y的亲戚,


y的亲戚也都是x的亲戚。

输入格式

第一行:三个整数n,m,p,(n<=5000,m<=5000,p<=5000),


分别表示有n个人,m个亲戚关系,询问p对亲戚关系。以下m行:


每行两个数Mi,Mj,1<=Mi,Mj<=N,表示Ai和Bi具有亲戚关系。


接下来p行:每行两个数Pi,Pj,询问Pi和Pj


是否具有亲戚关系。




输出格式

P行,每行一个’Yes’或’No’。表示第i个询问的答案为“具有”


或“不具有”亲戚关系。




输入样例:



版权声明:本文为guiguzi5512407原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。