zoukankan      html  css  js  c++  java
  • 并查集(union-find)算法

    定义 

      算法具体内容:https://www.cnblogs.com/tanxing/p/5600984.html

      算法简单介绍:此算法主要用于寻找两个对象之间是否有联系,可应用于寻找社交网络中,某两人是否有联系(有共同认识的人);或渗透系统中,判断此系统是否渗透。此算法分为联结和寻找两部分。

      联结:

        a和b联结,以a为根节点:即root(a)=a && root(b)=a;

        两联结体A和B结合(其中,A有3个元素A,A2,A3,root(A)=root(A2)=root(A3)=A; B有4个元素:B,B2,B3,B4,root(B)=root(B2)=root(B3)=root(B4)=B),由于B联结体元素更多,所以A联结体被并入B联结体即root(A)=B。

      寻找:  

        如果想知道啊a和b是否在同一联结体里(即a和b是否有联系),只需要比较root(a)是否等于root(b)。

      

    例题

    解答

      解题思路:记录每个联结体(connected components)的最大值。联结(union)时,比较两个联结体的最大值后,更新新联结体的最大值。

    .h:
    UCLASS()
    class ALGORITHM_API AAlgorithmExerciseTwo : public AActor
    {
        GENERATED_BODY()
        
    public:    
        // Sets default values for this actor's properties
        AAlgorithmExerciseTwo();
    
        // Called every frame
        virtual void Tick(float DeltaTime) override;
    
        //构造数组
        void InitIdArray(int N);
        //寻找根节点
        int Root(int i);
        //检查p,q是否相连
        bool Connected(int p, int q);
        //链接p和q
        void Union(int p, int q);
        //找小组里的最大值
        int FindMax(int i);
    
    protected:
        // Called when the game starts or when spawned
        virtual void BeginPlay() override;
    
    public:
    
    private:
    
        TArray<int> ID;
        TArray<int> SizeOfID;
        //记录并及时更新每个小组的最大值,即可完成查最大值的任务
        TArray<int> MaxOfID;
    
    };
    
    .cpp:
    
    // Sets default values
    AAlgorithmExerciseTwo::AAlgorithmExerciseTwo()
    {
         // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
        PrimaryActorTick.bCanEverTick = true;
    
    }
    
    // Called when the game starts or when spawned
    void AAlgorithmExerciseTwo::BeginPlay()
    {
        Super::BeginPlay();
        //测试
        InitIdArray(10);
        Union(1, 2);
        Union(6, 9);
        Union(1, 6);
        UKismetSystemLibrary::PrintString(this, "Root: " + FString::FromInt(Root(9)));
        UKismetSystemLibrary::PrintString(this, "Max: " + FString::FromInt(FindMax(1)));
    }
    
    // Called every frame
    void AAlgorithmExerciseTwo::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);
    
    }
    
    void AAlgorithmExerciseTwo::InitIdArray(int N)
    {
        //填充数组
        for (int i = 0; i < N; ++i)
        {
            ID.Add(i);
            //一开始,自己就是最大的
            MaxOfID.Add(i);
            //一开始只有自己一个
            SizeOfID.Add(1);
            
        }
    }
    //寻找根节点
    int AAlgorithmExerciseTwo::Root(int i)
    {
        while (i != ID[i])
        {
            ID[i] = ID[ID[i]];
            i = ID[i];
        }
        return i;
    }
    //检查p,q是否相连
    bool AAlgorithmExerciseTwo::Connected(int p, int q)
    {
        return Root(p) == Root(q);
    }
    //链接p和q
    void AAlgorithmExerciseTwo::Union(int p, int q)
    {
        int i = Root(p);
        int j = Root(q);
        //如果i==j,说明p,q已经连接了
        if (i == j) return;
        //谁大,则最大值取谁
        MaxOfID[i] < MaxOfID[j] ? MaxOfID[i] = MaxOfID[j] : MaxOfID[j] = MaxOfID[i];
        //大树吃小树:Link root of smaller tree to root of larger tree. 
        //注意:判断一棵树的大小,是根据它含有的子物体数量,而不是树的高矮来判断。
        if (SizeOfID[i] < SizeOfID[j])
        {
            ID[i] = j;
            SizeOfID[j] += SizeOfID[i];
        }
        else
        {
            ID[j] = i;
            SizeOfID[i] += SizeOfID[j];
        }
    }
    //返回小组中的最大值
    int AAlgorithmExerciseTwo::FindMax(int i)
    {
        return MaxOfID[i];
    }
  • 相关阅读:
    SPOJ GSS4 Can you answer these queries IV ——树状数组 并查集
    SPOJ GSS3 Can you answer these queries III ——线段树
    SPOJ GSS2 Can you answer these queries II ——线段树
    SPOJ GSS1 Can you answer these queries I ——线段树
    BZOJ 2178 圆的面积并 ——Simpson积分
    SPOJ CIRU The area of the union of circles ——Simpson积分
    HDU 1724 Ellipse ——Simpson积分
    HDU 1071 The area ——微积分
    HDU 4609 3-idiots ——FFT
    BZOJ 2194 快速傅立叶之二 ——FFT
  • 原文地址:https://www.cnblogs.com/mcomco/p/10039134.html
Copyright © 2011-2022 走看看