문제 링크
https://www.acmicpc.net/problem/1005
풀이
처음에 건물 건설에 조건이 없는 건물들을 짓기 시작한다고 생각해봅시다. 건물 $i$는 $D_i$에 건물이 완성될 것이고 건물 $i$를 지은 다음에 지을 수 있는 건물 $j$는 최소한 $D_i$ 이후에 지을 수 있습니다. 조건이 없는 건물들을 모두 지은 이후에는 “조건이 없는 건물들을 짓는 것”이 선행 조건이었던 건물들을 지을 수 있게 되고 지을 수 있는 가장 빠른 시간을 알고 있기 때문에 그 건물 $x$는 $mx_x + D_x$에 완성될 것이고 건물 $x$를 지은 다음에 지을 수 있는 건물 $y$는 최소한 $mx_x + D_x$이후에 지을 수 있습니다. 이를 건물 $w$에 도달할 때까지 반복한다면 $w$가 완성될 시간 $mx_w + D_w$를 알 수 있습니다.
하지만 건물 $i$를 짓기 위해 지어야 하는 건물들이 모두 지어졌는지 어떻게 확인할 수 있을까요? 문제에 나와있는 사진처럼 그래프의 관점에서 보면 정점(건물)에 향해있는 간선(indegree)에 연결된 건물을 지어서 모두 $mx_i$를 갱신했다면 그 건물을 지을 수 있음을 알 수 있습니다. 그러므로 정점 $i$를 향해있는 간선의 수를 $p_i$로 저장한다면 $mx_i$를 갱신할 때마다 $p_i$에 1을 빼는 것을 반복하다가 $p_i$가 0이 되었을 때 건물을 짓기 시작하면 되고 건물 $i$를 짓는 것이 선행조건 이었던 건물 $j$의 $mx_j$를 $mx_i + D_i$로 갱신합니다.
이를 BFS를 이용해 구현하면 되는데, 일반적으로 구현하는 방법처럼 도달했을 때 큐에 넣는 것이 아니고 마지막으로 방문했을 때 큐에 넣는다고 생각하고 구현하면 됩니다. 시간복잡도는 BFS를 하는 데에 걸리는 시간 $O(N+M)$입니다.
전체 코드
1 |
|