(전공복습) 데이터과학 4. 시각화
차례
간단한 위상 정렬(Topology Sort) 문제.
위상 정렬은 유향 비순환 그래프(Directed Acyclic Graph, DAG)에서 노드를 탐색하기 위한 순서를 결정하는 알고리즘이다.
가장 먼저 지을 수 있는 건물은 선행 건물이 없는 건물이다. 그런 건물들은 자신을 짓는 데에 걸리는 시간만 소요된다.
그 다음에는 방금 지은 그 건물들만을 선행 건물로 가지는 건물이다. 그런 건물들은 자신을 짓는 데에 걸리는 시간에 더해, 선행 건물을 짓는 데에 걸리는 시간 중 최대값이 추가로 소요된다.
즉, 위상 정렬을 수행해서 건물들의 짓는 순서를 결정하고, 걸리는 시간을 결정하기 위해 선행 노드들의 코스트 중 최대치를 찾아서 자신을 짓는 데에 걸리는 시간을 더하면 된다(다른 말로 DP의 성질도 가지고 있다).
그 외엔 특이한 점이 없는 문제.
#!python
from sys import stdin
input = stdin.readline
# 편의상 건물이 1이 아니라 0번부터 시작하도록 번호를 조정함
# graph[i] : i번 노드의 후행 노드들의 리스트
# node[i] : i번 노드를 짓는 데에 걸리는 시간
# degree[i] : i번 노드의 진입차수
# cost[i] : i번 노드의 총 비용(걸리는 시간, 즉 정답)
# q : 위상 정렬을 위한 큐(인데 사실은 스택)
n = int(input())
graph = [[] for _ in range(n)]
node = [0 for _ in range(n)]
degree = [0 for _ in range(n)]
cost = [0 for _ in range(n)]
q = []
# 입력 받는 부분
# 건물을 짓는 데에 걸리는 시간, 진입차수, 그래프 토폴로지를 갱신
for i in range(n):
t, *precs, _ = map(int, input().split())
node[i] = t
degree[i] = len(precs)
for prec in precs:
graph[prec-1].append(i)
# 진입차수가 0인 노드들을 모두 추가
# 그 노드들의 전체 비용은 그 노드 하나를 짓는 데에 걸리는 시간이다
for i in range(n):
if degree[i]:
continue
q.append(i)
cost[i] = node[i]
# 위상 정렬 수행
# 후행 노드(succ)를 짓는 데에 걸리는 시간은 그 후행 노드로의 간선을 가진 모든 노드의 걸리는 시간 중 최대치 + 후행 노드의 건설 시간
while q:
node_cur = q.pop()
for succ in graph[node_cur]:
degree[succ] -= 1
cost[succ] = max(cost[succ], cost[node_cur] + node[succ])
if not degree[succ]:
q.append(succ)
print(*cost, sep = '\n')
문제 링크 문제 링크
개요 선형적인 자료구조에서는 값에 접근하는 데에 \(O(1)\)이면 충분하지만, 대신 부분합을 구하는 데에는 \(O(N)\)이 필요하다. 그렇다면 이 자료구조를 이진 트리로 구성하면 어떨까? 값에 접근하는 데에 걸리는 시간이 \(O(\lg N)\)으로 늘어나지만 대신 부분합을 구하...
개요 다익스트라 알고리즘과 함께 Single Sourse Shortest Path(SSSP) 문제를 푸는 알고리즘이다. 즉, 한 노드에서 다른 모든 노드로 가는 최단 경로를 구하는 알고리즘이다. 다익스트라 알고리즘보다 느리지만, 음수 가중치 간선이 있어도 작동하며, 음수 가중치 사...
개요 다익스트라 알고리즘은 Single Sourse Shortest Path(SSSP) 문제를 푸는 알고리즘 중 하나이다. 즉, 한 노드에서 다른 모든 노드로 가는 최단 경로를 구하는 알고리즘이다. 단, 다익스트라 알고리즘은 음수 가중치 엣지를 허용하지 않는다. 이 경우에는 벨만-...