并查集

并查集

原理:

对于单独的点来说,进行染色处理,将拥有的最老祖先视为颜色,任意两点进行连接时,查找最老的祖先,如果相同就代表联通,不同就使一方最老祖先变为另一个最老祖先的祖先。

代码实现解释:

  1. find函数找最终的祖先
int find (int x)
{
    while(x!=fa[x])
    x=fa[x]=fa[fa[x]];
    return x;
}
  1. 将不同祖先的两点联合

for(int i=1;i<=m;i++)
{
    int x=find(a[i].x);
    int y=find(a[i].y); 
        join(x,y); 
}
void join(int x,int y)
{       
    if(x!=y)
    {
        fa[x]=y;
        nofa[y]+=nofa[x];//根据题目添加,板子中没有
        sum++;
    } 
}

代码

#include<iostream>
#include<algorithm>
using namespace std;
int fa[200005];
int nofa[200005];int sum=0;
struct node{
    int x,y;
}a[200005];

int find (int x)
{
    while(x!=fa[x])
    x=fa[x]=fa[fa[x]];
    return x;
}

void join(int x,int y)
{       
    if(x!=y)
    {
        fa[x]=y;
        nofa[y]+=nofa[x];//根据题目添加,板子中没有
        sum++;
    }
     
}
int main()
{
    int n,m;
    cin>>n>>m;
    
    for(int i=1;i<=m;i++)
    {
        cin>>a[i].x>>a[i].y;
    }
    for(int i=1;i<=n;i++)
    {
        fa[i]=i;
        nofa[i]=1;
    }
    for(int i=1;i<=m;i++)
    {
        int x=find(a[i].x);
        int y=find(a[i].y); 
          join(x,y); 
    }
    int ma=0;
    for(int i=1;i<=n;i++)
    {
      ma=max(ma,nofa[i]);
    }
    cout<<n-sum<<" "<<ma;
}

find优化

由于连祖先时可能会导致关系树越来越高,比如1->2->3->4->5->6,这时查找1的最老祖先就很麻烦,find优化后可以使得这一次查找链上的点全直连最老祖先

int find (int x)
{
   if(fa[x]==x) return x;
   return fa[x] = find(fa[x]);
}

加权优化

  1. 两个树连接时,如果随便挑一个作为另一个祖先,可能导致树的加长,列如:1->2->3->4->5->6和7->8(7为祖先)最优当然是以1为祖先连接,因为连接会使一个树的长度加1,选较短的树加一
  2. 添加一个rank数组标记树的层数即可
for(int i=1;i<=m;i++)
{
    int x=find(a[i].x);
    int y=find(a[i].y); 
        join(x,y); 
}
void join(int x,int y)
{       
    if(x!=y)
    {
        if(rank[x]>rank[y])
            {
                fa[y]=x;
                nofa[x]+=nofa[y];//根据题目添加,板子中没有
            }
        else
        {
            if(rank[x]==rank[y])
            {
                rank[y]++
            }
            fa[x]=y; 
            nofa[y]+=nofa[x];//根据题目添加,板子中没有
        }
        sum++;
    } 
}
posted @ 2024-05-22 00:53  WL1917  阅读(6)  评论(0)    收藏  举报