상호배타 집합을 표현하는 방법
상호배타 집합 연산
같은 집합의 원소들은 하나의 연결리스트로 관리한다.
연결리스트의 맨 앞의 원소를 집합의 대표 원소로 삼는다.
각 원소는 집합의 대표원소를 가리키는 링크를 갖는다.
하나의 집합(a disjoint set)을 하나의 트리로 표현한다.
자식 노드가 부모 노드를 가리키며 루트 노드가 대표자가 된다.

Make-Set(x)
p[x] <- x
Find-Set(x)
IF x == p[x] : RETURN x
ELSE : RETURN Find-Set(p[x])
Union(x, y)
p[Find-Set(y)] <- Find-Set(x)

균형있게 만들었다면 좋았을텐데..
편향 트리가 될 수 있을 것 같은데?
Rank를 이용한 Union


Path compression

// p[x] : 노드 x의 부모 저장
// rank[x] : 루트 노드가 x인 트리의 랭크 값 저장
Make-Set(x)
p[x] <- x
rank[x] <- 0
Find-Set(x)
IF x != p[x] : // x가 루트가 아닌 경우
p[x] <- Find-Set(p[x])
RETURN p[x]
Union(x, y)
Link(Find_Set(x), Find_Set(y))
Link(x, y)
IF rank[x] > rank[y] : // rank는 트리의 높이
p[y] <- x
ELSE
p[x] <- y
IF rank[x] == rank[y] :
rank[y]++
신장 트리 : 그래프의 모든 정점과 간선의 부분집합으로 구성되는 트리
최소 신장 트리 : 신장 트리 중, 사용된 간선들의 가중치의 합이 최소인 트리
특징
사용 이유
대표적인 방법
1) 최초, 모든 간선을 가중치에 따라 오름차순 정렬
2) 가중치가 가장 낮은 간선부터 선택하면서 트리 증가
3) n-1개의 간선이 선택될 때 까지 2를 반복



MST-KRUSKAL(G, w)
A <- 0 // 0 : 공잡헙
FOR vertex v in G.V // G.V : 그래프의 정점 집합
Make_Set(v) // G.E : 그래프의 간선 집합
G.E에 포함된 간선들을 가중치 w에 의해 정렬
FOR 가중치가 가장 낮은 간선 (u, v) G.E 선택 (n-1개)
IF Find_Set(u) != Find_Set(v)
A <- A U {(u, v)};
Union(u, v);
RETURN A