定义 

  算法具体内容: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];
}