🥕 문제 이름 : 커리큘럼
참고한 책 ; 나동빈 (2020). <이것이 취업을 위한 코딩 테스트다 with 파이썬>. 서울시: 한빛미디어. 303p
🍒 문제 분석
N개의 교양 강의를 듣고자 한다. 각 과목에는 선수과목이 있는 과목이 있고 없는 과목이 있다.
강의는 동시에 들을 수 있기 때문에, 가령 과목 3의 선수과목이 1과 2 일 때,
1이 30시간, 2가 20시간 걸린다고 한다면, 과목 3을 듣기 위해 선수과목을 듣는 시간은 30시간이 되는 셈이다.
따라서 강의 3의 강의 시간이 40시간이라면, 과목 3을 수강하기 까지 걸리는 시간은 70 시간이다.
N 개의 강의를 모두 듣는데 걸리는 최소 시간을 구해야 한다.
🥑 코드
# 입력
5
10 -1
10 1 -1
4 1 -1
4 3 1 -1
3 3 -1
from collections import deque
import copy
N = int(input()) # 강의 수
indegree = [0] * (N+1) # 진입 차수
time = [0] * (N+1) # 강의 시간
graph = [[] for i in range(N+1)] # 연결 그래프
for i in range(1, N +1):
data = list(map(int, input().split()))
time[i] = data[0]
for j in data[1:-1]:
indegree[i] += 1 # 선수 과목 하나 당 진입차수 +1
graph[j].append(i) # 선수 과목에다가 하위 과목을 추가한다.
# 위상 정렬 함수
def topology_sort():
result = copy.deepcopy(time)
q = deque()
for i in range(1, N+1):
if indegree[i] == 0:
q.append(i)
while q:
now = q.popleft()
for i in graph[now]: # now의 하위 과목들
result[i] = max(result[i], result[now]+time[i]) # 과목 i 의 시간 갱신
indegree[i] -= 1
if indegree[i] == 0 :
q.append(i)
for i in range(1, N+1):
print(result[i])
topology_sort()
- key idea : 선수 과목 중 시간이 더 많이 걸리는 것만 고려해주면 된다. ( 동시 수강이 가능하기 때문 )
- graph[ now ] 에는 과목 now 에 대한 하위 과목들이 담긴다.
- result[i] = max(result[i] , result[now] + time[i]) 을 통해 두가지를 구현할 수 있다.
1. result[i] 에 아직 선수 과목을 고려하지 않은 하위 과목의 강의 수강 시간이 담겨 있을 경우, 이를 선수 과목을 고려한 강의 시간으로 업데이트 해준다.
2. result[i] 에 선수 과목을 고려한 강의 수강 시간이 담겨 있지만, 그 값이 now라는 선수 과목을 고려한 수강시간 보다 작을 경우, 과목 now 를 고려한 강의 수강 시간으로 업데이트 해준다. ( key idea 에 적힌 이유로 인해 그렇다. )
'알고리즘' 카테고리의 다른 글
[알고리즘] 위상 정렬 (0) | 2022.06.29 |
---|---|
[알고리즘] 크루스칼 알고리즘 ( feat. union - find 알고리즘 ) (0) | 2022.06.29 |
[알고리즘] 서로소 집합 알고리즘 (0) | 2022.06.29 |
[알고리즘] 최단 경로 플로이드 워셜 알고리즘 (0) | 2022.06.21 |
[알고리즘] 다익스트라 최단경로 알고리즘 (0) | 2022.06.19 |