728x90
- '순서가 정해져 있는 작업'을 차례로 수행해야 할 때 그 순서를 결정해주기 위해 사용하는 알고리즘
- 사이클 발생X
- 위상 정렬은 시작점이 존재해야 함
- 2가지 해결책을 냄
- 현재 그래프는 위상 정렬이 가능한지
- 위상 정렬이 가능하다면 그 결과는 무엇인지
- 큐(Queue)를 이용한 방식
- 진입차수가 0인 정점을 큐에 삽입 (진입 차수 : 먼저 수행되는 것 갯수)
- 큐에서 원소를 꺼내 연결된 모든 간선을 제거
- 간선 제거 이후에 진입 차수가 0이 된 정점을 큐에 삽입
- 큐가 빌 때까지 2번~3번 과정을 반복
- 모든 원소를 방문하기 전에 큐가 빈다면 사이클 존재
- 방문했다면 큐에서 꺼낸 순서가 위상 정렬의 결과
from collections import deque
# 노드의 개수와 간선의 개수를 입력 받기
v, e = map(int,input().split())
# 모든 노드에 대한 진입차수는 0으로 초기화
indegree = [0]*(v+1)
# 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화
graph = [[] for _ in range(v+1)]
# 방향 그래프의 모든 간선 정보를 입력 받기
for _ in range(e):
# a가 b보다 먼저
a,b = map(int,input().split())
graph[a].append(b)
# 진입 차수 1 증가
indegree[b] += 1
# 위상 정렬 함수
def topology_sort():
# 알고리즘 수행 결과를 담을 리스트
result = []
# 큐 기능을 위한 deque
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)
# 해당 원소와 연결된 노드들의 진입차수에서 1빼기
for j in graph[now]:
indegree[j] -= 1
# 새롭게 진입 차수가 0이 되는 노드는 큐에 삽입
if indegree[j] == 0:
q.append(j)
# 위상 정렬을 수행한 결과 출력
print(*result)
topology_sort()
728x90
반응형
'TIL - 프로그래밍 > Python 알고리즘' 카테고리의 다른 글
[230228] n진법 구하기(with divmod) - Python (0) | 2023.02.28 |
---|---|
[프로그래머스] [3차] n진수 게임 - Python (1) | 2023.02.28 |
벨만 포드 알고리즘 (0) | 2022.12.04 |
[백준] 12851. 숨바꼭질 2 - Python (0) | 2022.10.14 |
[백준] 9935. 문자열 폭발 - Python (0) | 2022.09.23 |
댓글