안녕하세요. 서로소 집합은 다양한 알고리즘에 사용될 수 있습니다.
특히 서로소 집합은 무방향 그래프 내에서의 사이클을 판별할 때 사용할 수 있다는 특징이 있습니다.
앞서 union 연산은 그래프에서의 간선으로 표현될 수 있다고 했습니다.
따라서 간선을 하나씩 확인하면서 두 노드가 포함되어 있는 집합을 합치는 과정을 반복하는 것만으로도 사이클을 판별할 수 있습니다.
과정
1번) 각 간선을 확인하며 두 노드의 루트 노드를 확인합니다.
- 루트 노드가 서로 다르다면 두 노드에 대하여 union 연산을 수행합니다.
- 루트 노드가 서로 같다면 사이클(Cycle)이 발생한 것입니다.
2번) 그래프에 포함되어 있는 모든 간선에 대하여 1번 과정을 반복합니다.
예시
1
/ \
2---3
초기 상태에서는 모든 노드는 자기 자신을 가리키는 루트 노드입니다.
parent = [1, 2, 3]
가장 먼저 간선 (1, 2)를 확인합니다. 노드 1과 노드 2의 루트 노드는 각각 1과 2입니다.
따라서 더 큰 번호를 갖는 노드 2의 부모 노드를 1로 변경합니다.
parent = [1, 1, 3]
이어서 간선 (1, 3)을 확인합니다. 노드 1과 노드 3의 루트 노드는 각각 1과 3입니다.
따라서 더 큰 번호를 갖는 노드 3의 부모 노드를 1로 변경합니다.
parent = [1, 1, 1]
이후에 (2, 3) 간선을 확인합니다. 다만, 이때 노드 2와 노드 3이 이미 루트 노드로 '노드 1'을 가지고 있습니다.
다시 말해서 사이클이 발생한다는 것을 알 수 있습니다.
모든 간선을 확인한 결과, 루트 노드가 동일한 노드가 있으면 사이클이 발생한 것으로 판단합니다.
만약 간선을 확인하며 루트 노드가 동일한 경우가 나타나지 않으면, 그래프에 사이클이 없다고 판단할 수 있습니다.
서로소 집합을 활용한 사이클 판별 소스코드
# 서로소 집합을 활용하여 사이클 판별하는 함수: find_parent
def find_parent(parent, x):
# 현재 원소 x가 자기 자신을 가리키지 않으면
if parent[x] != x:
# 부모 노드를 재귀적으로 찾아서 경로 압축(Path Compression)을 수행한다.
parent[x] = find_parent(parent, parent[x])
# 최종적인 루트 노드를 반환한다.
return parent[x]
# 두 원소가 속한 집합을 합치는 함수: union_parent
def union_parent(parent, a, b):
# 각 원소 a와 b의 루트 노드를 찾는다.
a = find_parent(parent, a)
b = find_parent(parent, b)
# 작은 루트 노드를 가진 쪽을 큰 루트 노드를 가진 쪽의 자식으로 합친다.
if a < b:
parent[b] = a
else:
parent[a] = b
# 노드의 개수와 간선(Union 연산)의 개수 입력 받기
v, e = map(int, input().split())
parent = [0] * (v + 1) # 부모 테이블 초기화하기
# 부모 테이블상에서, 각 노드의 부모를 자기 자신으로 초기화한다.
for i in range(1, v + 1):
parent[i] = i
cycle = False # 사이클 여부를 판별하는 변수 초기화
for i in range(e):
a, b = map(int, input().split())
if find_parent(parent, a) == find_parent(parent, b):
# 두 노드의 루트 노드가 같다면 사이클이 발생한 것으로 판단한다.
cycle = True
break
else:
# 사이클이 발생하지 않았다면 두 노드를 합친다.
union_parent(parent, a, b)
if cycle:
print("사이클이 발생했습니다.")
else:
print("사이클이 발생하지 않았습니다.")
'개발 > CodingTest' 카테고리의 다른 글
다양한 알고리즘 - 위상정렬 (0) | 2024.01.21 |
---|---|
신장 트리 - 크루스칼 알고리즘 (0) | 2024.01.19 |
다양한 알고리즘 - 서로소 집합(경로 압축 기법) (0) | 2024.01.19 |
다양한 그래프 알고리즘 - 서로소 집합 (1) | 2024.01.19 |
[이코테] 전보(2) - 코딩테스트 - 다른풀이 (0) | 2024.01.18 |