[정의]
- 방향 그래프의 모든 노드를 방향성에 거스르지 않도록 순서대로 나열하는 것이다.
- 기본적으로 사이클이 발생하는 경우는 고려하지 않는다.
- 진입 차수라는 개념에 대해서 알아야할 필요성이 있다.
진입 차수란 특정한 노드로 들어오는 간선의 갯수를 의미한다.
경제학원론은 선수 과목이 없다. ( 진입 차수가 0 )
경제수학은 1 개의 선수 과목을 가지고 있다. ( 진입 차수가 1 )
중급 미시 경제학은 두 개의 선수 과목을 가지고 있다. ( 진입 차수가 2 )
다음을 위상 정렬 하게 되면
' 경제 학원론 -> 경제 수학 -> 중급 미시 경제학 '
이 될 것이다.
[위상 정렬]
- 마치 BFS 같이 하면 된다.
노드 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
진입 차수 | 0 | 1 | 1 | 2 | 1 | 2 | 1 |
다음의 그래프에서
먼저 진입차수가 0인 노드를 큐에 넣는다. 그 후 큐에서 꺼내면서 간선들을 제거한다.
그러면 노드 2와 노드 5의 진입 차수가 0이 되고, 새로히 큐에 들어가게 된다.
이를 반복하면 되는데, BFS 알고리즘과 그 원리가 유사하다.
큐가 아예 빌 때 까지 하면 된다.
from collections import deque
v, e = map(int, input().split())
# 진입 차수
indegree = [0] * (v+1)
graph = [[] for _ in range(v+1)]
for _ in range(e):
a, b = map(int, input().split()) # a에서 b로 가는 간선이다.
graph[a].append(b)
indegree[b] += 1 # 진입 차수가 추가된다.
# 위상 정렬 함수
def topology_sort():
result = [] # 위상 정렬의 순서를 담을 예정
q = deque()
# 진입 차수가 0인 노드를 큐에 삽입
for i in range(1, v+1):
if indegree[i] == 0 :
q.append(i)
while q:
now = q.popleft()
result.append(now)
for i in graph[now]:
indegree[i] -= 1
if indegree[i] == 0:
q.append(i)
print(result)
topology_sort()
[시간 복잡도]
- \( O(V+E) \) 의 시간이 소요된다.
- 차례대로 모든 노드를 확인하고 모든 간선을 제거하면 되기 때문이다.
참고한 책 ; 나동빈 (2020). <이것이 취업을 위한 코딩 테스트다 with 파이썬>. 서울시: 한빛미디어.
'알고리즘' 카테고리의 다른 글
[알고리즘] 위상정렬 교재 문풀 (0) | 2022.06.29 |
---|---|
[알고리즘] 크루스칼 알고리즘 ( feat. union - find 알고리즘 ) (0) | 2022.06.29 |
[알고리즘] 서로소 집합 알고리즘 (0) | 2022.06.29 |
[알고리즘] 최단 경로 플로이드 워셜 알고리즘 (0) | 2022.06.21 |
[알고리즘] 다익스트라 최단경로 알고리즘 (0) | 2022.06.19 |