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