부모 테이블 초기화
parent 배열은 각 정점의 root node(부모)를 표현한 배열이다.
초기에는 자기 자신이 루트노드가 되게 초기화 되어 있는 상태이다.(parent[i] = i)
parent 배열: {1}, {2}, {3}, {4}
1 | 2 | 3 | 4 |
---|---|---|---|
1 | 2 | 3 | 4 |
가중치의 오름차순 정렬 순서대로 간선 1-2를 선택한다.
정점1과 정점2를 연결하면서 Union 연산에 의해 두 집합이 합쳐진다.
이 때, Union 연산으로 두 정점의 루트 노드(부모)가 다른지 판단하고 다르다면 합친다.
해당 집합 내에서 제일 작은 숫자가 그 집합에서의 루트 노드가 되게끔 가정한다.
따라서 parent[2] = 1이 된다.
parent 배열: {1, 2}, {3}, {4}
1 | 2 | 3 | 4 |
---|---|---|---|
1 | 1 | 3 | 4 |
간선 1-4를 선택한다.
정점1의 루트노드는 1이고 정점4의 루트노드는 4이다. 두 정점의 루트 노드가 다르기 때문에 Union 연산으로 합칠 수 있다.
따라서 parent[4] = 1이 된다.
parent 배열: {1, 2, 4}, {3}
1 | 2 | 3 | 4 |
---|---|---|---|
1 | 1 | 3 | 1 |
간선 2-4 선택
정점2의 루트노드는 1이고 정점4의 루트노드도 1이다. 두 정점의 루트 노드가 같기 때문에 합칠 수 없다.(사이클을 형성하기 때문)
-> 사이클이 생기는지 확인하는 방법: 각 노드의 루트 노드가 동일한지 아닌지를 보면 알 수 있다.
// 정점 집합 클래스(Union-Find 연산)
class VertexSets{
int parent[MAX_VERTICES];
int size;
public:
VertexSets(int nSets){
size = nSets;
for(int i=0; i<nSets; i++) parent[i] = -1;
}
bool IsRoot(int i) {return parent[i] < 0;}
int findSet(int vertex){
int id = vertex;
while(!IsRoot(id)) id = parent[id];
return id;
}
void unionSets(int s1, int s2){
parent[s2] = s1;
size--;
}
void print(int i){
cout << parent[i] << endl;
}
};