[백준/JAVA] BOJ 14567 - 선수과목

NAGANG LEE·2025년 7월 7일

알고

목록 보기
114/118

위상 정렬 좋아

👀 문제

14567번: 선수과목 ✨ 골드 5

올해 Z대학 컴퓨터공학부에 새로 입학한 민욱이는 학부에 개설된 모든 전공과목을 듣고 졸업하려는 원대한 목표를 세웠다. 어떤 과목들은 선수과목이 있어 해당되는 모든 과목을 먼저 이수해야만 해당 과목을 이수할 수 있게 되어 있다. 공학인증을 포기할 수 없는 불쌍한 민욱이는 선수과목 조건을 반드시 지켜야만 한다. 민욱이는 선수과목 조건을 지킬 경우 각각의 전공과목을 언제 이수할 수 있는지 궁금해졌다. 계산을 편리하게 하기 위해 아래와 같이 조건을 간소화하여 계산하기로 하였다.

  1. 한 학기에 들을 수 있는 과목 수에는 제한이 없다.
  2. 모든 과목은 매 학기 항상 개설된다.

모든 과목에 대해 각 과목을 이수하려면 최소 몇 학기가 걸리는지 계산하는 프로그램을 작성하여라.


예제 입력

3 2
2 3
1 2

예제 출력

1 2 3

🔑 키포인트

다이나믹 프로그래밍 위상 정렬


✍️ 코드

📍 위상 정렬을 사용해 순서가 있는 bfs를 실행해 준다. 몇 학기가 걸리는지는 answer[다음 과목] = answer[현재 수강한 과목] + 1 와 같은 점화식을 사용해 저장해 주었다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.ArrayList;
import java.util.LinkedList;

public class BOJ14567_선수과목 {
    static ArrayList<ArrayList<Integer>> graph;
    static int[] depth, answer;
    static Queue<Integer> q;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        graph = new ArrayList<>();
        depth = new int[n + 1];
        answer = new int[n + 1];
        q = new LinkedList<>();

        for (int i = 0; i < n + 1; i++) {
            graph.add(new ArrayList<>());
        }
        for (int i = 0; i < m; i++) {
            st = new StringTokenizer(br.readLine());
            int prev = Integer.parseInt(st.nextToken());
            int next = Integer.parseInt(st.nextToken());
            graph.get(prev).add(next);
            depth[next] += 1;
        }

        for (int i = 1; i < n + 1; i++) {
            if (depth[i] == 0) {
                q.offer(i);
                answer[i] = 1;
            }
        }

        bfs();

        StringBuilder sb = new StringBuilder();
        for (int i = 1; i < n + 1; i++) {
            sb.append(answer[i] + " ");
        }
        System.out.println(sb.toString());
    }

    static void bfs() {
        while (!q.isEmpty()) {
            int now = q.poll();
            for (int next : graph.get(now)) {
                if (--depth[next] == 0) {
                    q.offer(next);
                    answer[next] = answer[now] + 1;
                }
            }
        }
    }
}
profile
모바일 개발자를 목표로 하고 있어요 💭

0개의 댓글