문제 요약
| 항목 | 설명 |
|---|---|
| 입력 | 작업 수 N, 각 작업 시간, 선행 작업 개수와 번호 |
| 조건 | 선행 관계가 없는 작업끼리는 동시에 수행 가능 |
| 목표 | 모든 작업을 끝내는 데 필요한 최소 시간 구하기 |
| 핵심 | 위상정렬 + 각 작업의 가장 빠른 완료 시간 계산 |
문제는 단순히 작업 순서를 하나 구하는 것이 아니라, 모든 작업이 끝나는 최소 시간을 구해야 합니다. 서로 독립인 작업은 동시에 진행할 수 있기 때문에 “순서”만이 아니라 “시간 누적”이 핵심입니다. [Source](https://www.acmicpc.net/problem/2056)
이 문제에서 제일 중요한 감각
1. 위상정렬만으로는 부족하다
위상정렬은 “어떤 순서로 가능한가”를 알려줍니다. 그런데 이 문제는 모든 작업 완료까지 걸리는 최소 시간을 구해야 하므로, 작업 순서만 알아서는 부족합니다.
2. 각 작업의 완료 시간을 기억해야 한다
어떤 작업이 끝나는 가장 빠른 시간을 저장해두고, 그 값을 다음 작업 계산에 계속 사용해야 합니다. 이름은 보통 dp라고 많이 부르지만, 이 글에서는 더 직관적으로 finish_time = 작업 완료 시간 배열이라고 보겠습니다.
3. 선행 작업이 여러 개면 가장 늦게 끝나는 작업을 기다려야 한다
어떤 작업을 시작하려면 선행 작업이 모두 끝나야 하므로, 시작 시점은 선행 작업들 중 가장 늦게 끝나는 작업에 의해 결정됩니다. 그래서 최대값 비교가 필요합니다. [Source](https://www.acmicpc.net/problem/2056)
finish_time이 왜 필요한가?
예시 구조
1번 작업 (3)
↙ ↘
2번 작업 (5) 3번 작업 (4)
↘ ↙
4번 작업 (6)
시간 계산
1번 완료 시간 = 3
2번 완료 시간 = 3 + 5 = 8
3번 완료 시간 = 3 + 4 = 7
4번 완료 시간 = max(8, 7) + 6 = 14
여기서 4번 작업은 2번과 3번이 모두 끝나야 시작할 수 있으므로, 더 빨리 끝난 3번 기준이 아니라 더 늦게 끝난 2번 기준으로 기다려야 합니다.
finish_time[next] = max(finish_time[next], finish_time[now] + work_time[next])
그래프를 어떻게 만들까?
문제에서 “A 작업이 끝나야 B 작업 시작 가능”이라면, 그래프 간선은 A → B로 두어야 합니다.
선행 작업 → 현재 작업
예시
1번을 끝내야 3번 가능 → 1 → 3
2번과 4번이 끝나야 5번 가능 → 2 → 5, 4 → 5
따라서 인접 리스트에는 graph[선행작업].append(현재작업) 형태로 저장해야 합니다.
예제 힌트로 보는 시간 흐름
문제 힌트 시간표
문제 페이지에 제시된 예제 힌트는 아래와 같습니다. [Source](https://www.acmicpc.net/problem/2056)
| 작업 | 실행 구간 | 완료 시간 |
|---|---|---|
| 1번 | 0 ~ 5 | 5 |
| 2번 | 5 ~ 6 | 6 |
| 3번 | 6 ~ 9 | 9 |
| 4번 | 5 ~ 11 | 11 |
| 5번 | 11 ~ 12 | 12 |
| 6번 | 11 ~ 19 | 19 |
| 7번 | 19 ~ 23 | 23 |
왜 마지막 정답이 23인가?
모든 작업은 동시에 시작 가능한 것은 동시에 진행되지만, 결국 전체 작업이 끝나는 시간은 각 작업 완료 시간 중 가장 큰 값이 됩니다.
전체 정답 = max(finish_time)
최종 코드
from collections import deque
import sys
input = sys.stdin.readline
n = int(input())
graph = [[] for _ in range(n + 1)]
indegree = [0] * (n + 1)
work_time = [0] * (n + 1)
finish_time = [0] * (n + 1)
for i in range(1, n + 1):
data = list(map(int, input().split()))
work_time[i] = data[0]
cnt = data[1]
for j in range(2, 2 + cnt):
prev = data[j]
graph[prev].append(i)
indegree[i] += 1
queue = deque()
for i in range(1, n + 1):
if indegree[i] == 0:
queue.append(i)
finish_time[i] = work_time[i]
while queue:
now = queue.popleft()
for next_node in graph[now]:
finish_time[next_node] = max(finish_time[next_node], finish_time[now] + work_time[next_node])
indegree[next_node] -= 1
if indegree[next_node] == 0:
queue.append(next_node)
print(max(finish_time))
코드 한 줄씩 핵심 설명
자주 틀리는 부분
한 번에 정리
이 문제의 핵심 한 문장
위상정렬로 작업 순서를 처리하면서, 각 작업의 가장 빠른 완료 시간을 계속 갱신해야 하고, 선행 작업이 여러 개라면 가장 늦게 끝나는 선행 작업 기준으로 현재 작업 시간이 결정됩니다.
문제는 여러 작업이 선행 관계를 가질 때 모든 작업을 완료하는 최소 시간을 구하는 것입니다. 따라서 단순 위상정렬이 아니라, 위상정렬 과정에서 각 작업의 완료 시간을 함께 계산해야 합니다. [문제 바로가기] [Source](https://www.acmicpc.net/problem/2056)
'크래프톤 정글 > 정글에서 문제풀기' 카테고리의 다른 글
| [정글 코어타임] - [리트코드]104. Maximum Depth of Binary Tree (0) | 2026.03.24 |
|---|---|
| [정글 코어타임] - [리트코드]102. Binary Tree Level Order Traversal (0) | 2026.03.24 |
| [정글 알고리즘] - [중]-백준 5639 이진 검색 트리 - 골드4 (1) | 2026.03.23 |
| [정글 알고리즘] - [중]-백준 11724 연결 요소의 개수 풀이 실버2 (4) | 2026.03.21 |
| [정글 알고리즘] - [중]-백준 1260 DFS와 BFS 풀이 실버2 (0) | 2026.03.21 |