카테고리 없음

위상정렬-동빈북

백엔드 개발자 2021. 10. 13. 13:07

순서가 정해져있는 일련의 작업을 차례로 수행해야 할 때 사용할 수 있는 알고리즘.

 

방향그래프의 모든 노드를 방향성에 거스르지 않도록 순서대로 나열하는 것이다.

 

 

ex:선수과목을 고려한 학습순서 설정

: 자료구조를 수강한 후 알고리즘강의 수강을 권장하는 컴공 커리큘럼

자료구조, 알고리즘을 노드로 표현하고 둘사이를 잇는 방향성을 갖는 간선을 그릴 수 있음.

 

그래프에서 선후관계가 있으면 위상정렬로 모든 선후 관계를 지키는 전체순서를 계산할 수 있음.

 

진입차수: 특정 노드로 들어오는 간선의 개수

 

 

알고리즘:

1: 맨처음 진입차수가 0인 노드를 큐에 넣는다.

2. 큐가 빌 때까지 반복

  2-1 큐에서 원소를 꺼내서 해당 노드에서 출발하는 간선을 모두 제거

  2-2 새롭게 진입차수가 0이 된 노드를 큐에 넣는다.

 

만약 모든 원소를 방문하기 전에 큐가 비면 이건 사이클이 생긴것이다.

사이클이 생기면 사이클에 포함된 원소는 전부 큐에 못들어간다.

 

시간복잡도 O(V+E)

위상정렬은 차례로 모든 노드를 확인하면서 해당노드에서 출발하는 간선을 차례대로 제거해야함.

그래서 노드와 간선을 모두 확인함.

 

from collections import deque
#노드의 개수와 간선 개수 입력받기
v,e=map(int, input().split())
#모든 노드에 대한 진입차수 0으로 초기화
indegree=[0]*(v+1)
#각 노드에 연결된 간선정보를 담기위한 연결리스트 초기화
graph=[[] for i in range(v+1) ]

#방향 그래프의 모든 간선 정보 입력받기
for i in range(e):
    a
,b=map(int,input().split())
    graph[a].append(b)
# a에서 b로 이동가능
   
indegree[b]+=1# 진입차수 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)
   
for i in result:
       
print(i, end=' ')
topology_sort()