알고리즘
[알고리즘] 위상 정렬(Topological Sort)
최MAX
2022. 3. 30. 18:49
위상 정렬 (Topological Sort)
순서가 정해져있는 작업을 차례로 수행해야 할 때 그 순서를 결정해주기 위해 사용하는 알고리즘.
- 위상 정렬은 DAG (Directed Acyclic Graph, 방향성 비순환 그래프)에서만 사용 가능
알고리즘 과정
- 각 노드(vertex)의 진입간선을 저장한다.
- 진입간선이 없는 노드를 큐에 push
- 큐에서 노드를 하나씩 꺼내서 위상정렬에 넣어준다.
- 꺼낸 노드와 연결된 노드의 위상을 하나씩 낮추고 간선(edge)을 없앤다.
- 진입간선이 없는 노드를 큐에 다시 넣어준다.
- 3-5번을 큐가 빌 때까지 반복한다.
동작 예시
"라면 끓이기"에 비유
1. 진입 간선이 0인 노드 Queue에 넣기
"라면 끓이기"로 예를 들어보자면, 라면을 끓이기 위해서 우선 [냄비에 물 붓기]와 [라면 사오기]가 라면을 끓여먹기 위한 기초 작업이므로 진입 간선 (해당 노드로 들어오는 간선)이 없다. 따라서 [냄비에 물 붓기 (1)], [라면 사오기(2)] 작업은 진입 간선이 0이고, [물 끓이기(3)]의 진입 간선은 2개, [라면 넣기(4)]는 1개이다.
2. Queue에서 1 (Queue.front()) 꺼내서 위상 정렬에 넣기
이미 queue에 들어갔었던 1, 2를 제외하고 진입 간선이 0인 노드가 없으므로 queue에 아무것도 들어가지 않는다.
3. Queue에서 2 꺼내기
Queue에서 꺼낸 2를 위상 정렬에 넣어준다. 2를 꺼내면서 3으로 향하는 진입 간선이 0이 되었으므로 3을 Queue에 push 해준다.
4. Queue에서 3 꺼내기
마찬가지로 3을 Queue에서 뺀 후 위상 정렬에 넣어준다. 이후 4를 Queue에 push.
이후 Queue에서 4를 빼주면 Queue에 아무 것도 없으므로 종료하고, 최종 위상 정렬 결과 [1 - 2 - 3 - 4] 를 확인할 수 있다.
바로 문제를 풀어보자.
[BOJ] 2252번 '줄 세우기'
소스 코드 (C++)