각 건물의 최소시간을 구하기 위해 위상정렬 과 DP 를 사용했습니다
다음 건물을 짓는 최소 시간 = max(다음 건물을 짓는 최소 시간, 현재 건물을 짓는 최소 시간 + 현재 건물을 짓는 시간)
위의 식으로 도출된 최소시간에 다음 건물을 짓는 시간을 더하게 된다면 건물을 짓는데 걸리는 최소시간을 얻을 수 있습니다
indegree : 해당하는 인덱스의 앞에 오는 수의 개수를 가진 배열
graph : 해당 인덱스에 해당하는 숫자의 뒤에 오는 숫자들의 리스트
if (preBuildingNum == -1) {
buildings.add(new Building(i, time));
continue;
}
buildings.add(new Building(i, time));
while (preBuildingNum != -1) {
graph[preBuildingNum].add(i);
indegree[i]++;
preBuildingNum = scanner.nextInt();
}
for (int i = 1; i <= N; i++)
if (indegree[i] == 0)
queue.add(i);
while(!queue.isEmpty()){
int current = queue.poll();
for(int i = 0; i < graph[current].size(); i++){
int next = graph[current].get(i);
indegree[next]--;
minTime[next] = Math.max(minTime[next], minTime[current] + buildings.get(current).time);
if(indegree[next] == 0)
queue.add(next);
}
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
class Building{
int num;
int time;
public Building(int num, int time){
this.num = num;
this.time = time;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N;
int[] minTime;
int[] indegree;
ArrayList<Integer>[] graph;
ArrayList<Building> buildings = new ArrayList<>();
Queue<Integer> queue = new LinkedList<>();
N = scanner.nextInt();
minTime = new int[N + 1];
indegree = new int[N + 1];
graph = new ArrayList[N + 1];
for (int i = 0; i <= N; i++)
graph[i] = new ArrayList<>();
buildings.add(new Building(0,0)); // add 0 index building
for (int i = 1; i <= N; i++) {
int time = scanner.nextInt();
int preBuildingNum = scanner.nextInt();
if (preBuildingNum == -1) {
buildings.add(new Building(i, time));
continue;
}
buildings.add(new Building(i, time));
while (preBuildingNum != -1) {
graph[preBuildingNum].add(i);
indegree[i]++;
preBuildingNum = scanner.nextInt();
}
}
for (int i = 1; i <= N; i++)
if (indegree[i] == 0)
queue.add(i);
while(!queue.isEmpty()){
int current = queue.poll();
for(int i = 0; i < graph[current].size(); i++){
int next = graph[current].get(i);
indegree[next]--;
minTime[next] = Math.max(minTime[next], minTime[current] + buildings.get(current).time);
if(indegree[next] == 0)
queue.add(next);
}
}
for (int i = 1; i <= N; i++)
System.out.println(buildings.get(i).time + minTime[i]);
scanner.close();
}
}