【算法】无趣的并查集

并查集


定义

把许多有关系的人合并成一个集合
然后询问其中的人是否有关系的时候用并查集


思路

存图
每一次输入判断他们的祖先是否同一个
不同的话就把两个数的祖先改成同一个
最后的询问只要O(1)


例子和代码

一个入门的并查集题目

洛谷P1551:https://www.luogu.org/problemnew/show/P1551

代码:

#include<iostream>
using namespace std;
int father[5001];
int n,m,p;
int find(int x)
{
    if(father[x]!=x)//路径压缩优化
    father[x]=find(father[x]);//把路上的所有点祖先全部改掉
    return father[x];
}
void unionn(int x,int y)
{
    father[y]=x;//y的祖先为x的祖先
                //相当于合并祖先
}
int main()
{
    cin>>n>>m>>p;
    for(int i=1;i<=n;i++)
    {
        father[i]=i;//所有数据初始祖先为自己
                    //独立的一个数为一个集合
    }
    for(int i=1;i<=m;i++)
    {
        int x,y;
        cin>>x>>y;
        int r1,r2;
        r1=find(x);
        r2=find(y);//寻找两个数的祖先
        if(r1!=r2)//如果不是同一个祖先
        {
            unionn(r1,r2);//合并
        }
    }
    for(int i=1;i<=p;i++)
    {
        int x,y;
        cin>>x>>y;
        if(find(x)==find(y))//如果是同一个祖先
        {
            cout<<"Yes"<<endl;//是
        }
        else
        cout<<"No"<<endl;//否
    }
    
}

猜你喜欢

转载自www.cnblogs.com/BrokenString/p/9279516.html
今日推荐