Algorithm

[Algorithm] 커리큘럼

씬프 2021. 5. 29. 15:15
반응형

문제

동빈이는 온라인으로 컴퓨터 공학 강의를 듣고 있다. 이때 각 온라인 강의는 선수 강의가 있을 수 있는데, 선수 강의가 있는 강의는 선수 강의를 먼저 들어야만 해당 강의를 들을 수 있다. 예를 들어 '알고리즘' 강의의 선수 강의로 '자료구조'와 '컴퓨터 기초'가 존재한다면, '자료구조'와 '컴퓨터 기초'를 모두 들은 이후에 '알고리즘' 강의를 들을 수 있다.

 

동빈이는 총 N개의 강의를 듣고자 한다. 모든 강의는 1번부터 N번까지의 번호를 가진다. 또한 동시에 여러 개의 강의를 들을 수 있다고 가정한다. 예를 들어 N=3일 때, 3번 강의의 선수 강의로 1번과 2번 강의가 있고, 1번과 2번의 선수 강의는 없다고 가정하자. 그리고 각 강의에 대하여 강의 시간이 다음과 같다고 가정하자.

 

1번 강의 : 30시간, 2번 강의 : 20시간, 3번 강의 : 40시간

 

이 경우 1번 강의를 수강하기까지 최소 시간 30시간, 2번 강의를 수강하기까지 20시간, 3번 강의를 수강하기까지 최소 시간은 70시간이다.

 

동빈이가 듣고자 하는 N개의 강의 정보가 주어졌을 때, N개의 강의에 대해 수강하기까지 걸리는 최소 시간을 각각 출력하는 프로그램을 작성하시오.

 

입력 조건

첫째 줄에 동빈이가 듣고자 하는 강의의 수 N이 주어진다.

두번째 줄부터 N+1번째 줄까지 각 강의의 시간과 먼저 들어야 하는 강의들의 번호가 주어진다.

각 강의 번호는 1부터 N까지로 구성되며, 각 줄은 -1로 끝난다.

 

출력 조건

N개의 강의에 대해 수강하기까지 걸리는 최소시간을 한 줄에 하나씩 출력한다.

 

풀이

선수과목이 있는 것으로 생각하여 위상정렬을 생각했다.

 

import java.util.*;

class Main {

  public static int n;
  public static int[] indegree = new int[501];
  public static int[] timeList = new int[501];
  public static int[] result = new int [501];
  public static ArrayList<ArrayList<Integer>> list = new ArrayList<>();

  public static void main(String[] args) {
    
    Scanner sc = new Scanner(System.in);
    n = sc.nextInt();
    for (int i = 0; i <= n; i++) {
      list.add(new ArrayList<Integer>());
    }

    for (int i = 1; i <= n; i++) {
      int x = sc.nextInt();
      timeList[i] = x;
      while (true) {
        x = sc.nextInt();
        if (x == -1) break;
        indegree[i]++; // i 과목을 듣는데 x과목이 필요하다
        // i의 진입차수가 1개 있다. 라고 표현, 근데
        // 나는 반대로 생각함.
        list.get(x).add(i); //here
      }
    }

    System.arraycopy(timeList, 0, result, 0, n+1);

    Queue<Integer> q = new LinkedList<>();
    for (int i = 1; i <= n; i++) {
      if (indegree[i] == 0) {
        q.offer(i);
      }
    }

    while (!q.isEmpty()) {
      int now = q.poll();
      for (int i = 0; i < list.get(now).size(); i++) {
        int tmp = list.get(now).get(i);
        indegree[tmp]--;
        result[tmp] = Math.max(result[tmp], result[now] + timeList[tmp]);
        if (indegree[tmp] == 0) {
          q.offer(tmp);
        }
      }
    }

    for (int i = 1; i <= n; i++) {
      System.out.println(result[i]);
    }

    sc.close();

  } // end main
}

'Algorithm' 카테고리의 다른 글

[Algorithm] 곱하기 혹은 더하기  (0) 2021.05.31
[Algorithm] 모험가 길드  (0) 2021.05.30
[Algorithm] 도시 분할 계획  (0) 2021.05.28
[Algorithm] 팀 결성  (0) 2021.05.27
[Algorithm] 서로소 집합 자료구조  (0) 2021.05.26