일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- blockchain
- 딥다이브
- react
- 백준
- Queue
- var
- 변수
- solidity
- 함수
- Javascript
- 프로퍼티
- Execution context
- Deep Dive
- 알고리즘
- 클로저
- Algorithm
- git pull
- 리액트
- frontend
- let
- nft
- BOJ
- Interview
- 정렬
- 파이썬
- Python
- 실행 컨텍스트
- 자바스크립트
- 솔리디티
- 블록체인
Archives
- Today
- Total
공부하자
[Algorithm] 위상 정렬 본문
위상 정렬
위상 정렬은 순서가 정해져 있는 작업을 차례로 수행해야 할 때, 순서를 결정해주는 알고리즘
DAG(Directed Acyclic Graph)그래프여야 함. 방향성이 있고, 사이클이 없는 그래프
위상 정렬의 시간 복잡도는 O(V + E)로 문제를 해결할 수 있음.
힙 자료구조와 함께 적용하면 쉽게 문제를 풀 수 있음.
위상정렬 알고리즘 순서
1) 진입 차수(Indegree, 자기 자신으로 오는 간선을 의미)가 0인 정점을 큐에 삽입한다.
2) 큐에 원소를 꺼내 해당 원소와 간선을 제거한다.
3) 제거 이후에 진입 차수가 0이 된 정점을 큐에 삽입한다.
4) 큐가 빌 때까지 2) ~ 3) 과정을 반복한다.
* 사이클이 존재하면 진입차수가 0인 정점을 찾을 수 없기때문에 위상 정렬 적용 불가. 모든 원소를 방문하기 전에 큐가 빈다면 사이클이 존재하는 것
* 모든 원소를 방문했다면 큐에서 꺼낸 순서가 위상 정렬의 결과이다.
위상 정렬 예시 문제
BOJ 1766번 문제집
https://www.acmicpc.net/problem/1766
<풀이 코드>
import heapq
n, m = map(int, input().split())
# 각 노드에 연결되 간선 정보를 담기 위한 연결 리스트 초기화
array = [[] for i in range(n + 1)]
# 모든 노드에 대한 진입차수는 0으로 초기화
indegree = [0] * (n + 1)
heap = []
result = []
# 방향 그래프의 모든 간선 정보를 입력받기
for _ in range(m):
x, y = map(int, input().split())
# 정점 A에서 B로 이동 가능
array[x].append(y)
# 진입 차수를 1 증가
indegree[y] += 1
# 진입 차수가 0인 노드를 큐에 삽입
for i in range(1, n + 1):
if indegree[i] == 0:
heapq.heappush(heap, i)
# 큐가 빌 때까지 반복
while heap:
# 큐에서 가장 작은 원소를 꺼냄
data = heapq.heappop(heap)
result.append(data)
# 해당 원소와 연결된 노드 제거
for y in array[data]:
indegree[y] -= 1
# 제거 이후에 진입 차수가 0이 된 정점을 큐에 삽입
if indegree[y] == 0:
heapq.heappush(heap, y)
for i in result:
print(i, end=' ')
'Algorithm' 카테고리의 다른 글
[Algorithm] 소수 판별 & 소수 리스트 만들기 (1) | 2022.12.27 |
---|---|
[Algorithm] 투 포인터(Two Pointers) 알고리즘 with BOJ 3273번 (0) | 2022.12.21 |
[자료구조] 링크드 리스트(Linked List) (0) | 2022.07.06 |
[코테 공부] 정렬 정리 (0) | 2022.04.18 |
스택(Stack) & Memoization (0) | 2021.10.20 |
Comments