并查集

例题洛谷P2978
用途:判断图中有几个连通块
1.int pre[1000]; 记录了每个人的上级是谁。如果一个人的上级就是他自己,那说明他就是队长,一个块只能有一个队长
2.查找

int find(int x)                       
{
   if(pre[r]==r)
        return r;
    else find(pre[r]);                   
}

3.合并

void join(int x,int y)                     
{
    int fx=find(x), fy=find(y);            
    if(fx != fy)                             
        pre[fx]=fy;                       
}

4.路径压缩
因为不关心连通的结构,有可能是个很长的链状结构,理想的状况是,所有人的上级都是自己队伍里面的队长,这样需要只要一次操作就能判断是否是一个队伍的。
因此,每次根据每个点查找到队长后将该点的上级设为队长。
同时为了使合并后的树不再退化,即合并后层数尽量不变,可以用rank[1000]表示树的层数

改进后的代码

int pre[1000];
int rank[1000];
//初始化
for(int i=0;i<n;i++)
{
   pre[i]=I;
   rank[I]=0;
}
//查找函数
int find(int x)     
{
   if(pre[x] == x){       
       return x;      
   }
   return pre[x] =find (pre[x]);   
}
//合并函数
void Union(int i,int j)
{
   i=find(i);
   j=find(j);
   if(i==j) return ;
   if(rank[i]>rank[j]) pre[j]=i;
   else
   {
       if(rank[i]==rank[j]) rank[j]++;  
       pre[i]=j;
   }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 更多的可以参考我的博客,也在陆续更新inghttp://www.hspweb.cn/ 例子是最小差值生成树:给定一...
    Superbsco阅读 1,271评论 0 0
  • 并查集原理我将举一个更有爱的例子。 话说江湖上散落着各式各样的大侠,有上千个之多。他们没有什么正当职业,整天背着剑...
    扎Zn了老Fe阅读 566评论 0 0
  • 本文主要包括以下内容: 并查集的概念 并查集的操作 并查集的实现和优化Quick FindQuick Union基...
    Chiclaim阅读 1,611评论 1 2
  • 并查集(Disjiont-set) [TOC] 更新5/23/2018 更新路径压缩代码 简介 wiki上关于并查...
    前几阅读 2,258评论 0 2
  • 今天早上是被姐姐的一声“下了一院的雪”吵醒的。不知何时,睁眼的第一件事变成了摸手机,看青椒优秀教师群的消息,可以说...
    会宁407闫鑫鑫阅读 429评论 0 0