14567번: 선수과목 (Prerequisite)

Joo·2022년 11월 23일

백준

목록 보기
111/113

https://www.acmicpc.net/problem/14567

문제

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

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

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

입력

첫 번째 줄과목의 수 N(1 ≤ N ≤ 1000)과 선수 조건의 수 M(0 ≤ M ≤ 500000)이 주어진다.

선수과목 조건은 M개의 줄에 걸쳐 한 줄에 정수 A B 형태로 주어진다. A번 과목B번 과목의 선수과목이다.

A < B인 입력만 주어진다. (1 ≤ A < B ≤ N)

출력

1번 과목부터 N번 과목까지 차례대로 최소 몇 학기에 이수할 수 있는지를 한 줄에 공백으로 구분하여 출력한다.

예제 입력 1

3 2
2 3
1 2

예제 출력 1

1 2 3

예제 입력 2

6 4
1 2
1 3
2 5
4 5

예제 출력 2

1 2 2 1 3 1

풀이

package topological_sort;

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

public class Main_14567 {

    private static int numberOfSubject;
    private static int numberOfPrerequisite;
    private static int[] inDegree;
    private static int[] completeSemester;
    private static ArrayList<Integer>[] adjacencyList;
    private static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) throws IOException {
        input();
        process();
        output();
    }

    private static void input() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        st = new StringTokenizer(br.readLine());
        numberOfSubject = Integer.parseInt(st.nextToken());
        numberOfPrerequisite = Integer.parseInt(st.nextToken());

        adjacencyList = new ArrayList[numberOfSubject + 1];
        inDegree = new int[numberOfSubject + 1];
        completeSemester = new int[numberOfSubject + 1];

        for (int i = 1; i <= numberOfSubject; i++) {
            adjacencyList[i] = new ArrayList<>();
        }

        for (int i = 0; i < numberOfPrerequisite; i++) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());

            adjacencyList[a].add(b);
            inDegree[b]++;
        }
    }

    private static void process() {
        Queue<Integer> queue = new LinkedList<>();

        for (int subject = 1; subject <= numberOfSubject; subject++) {
            if (inDegree[subject] == 0) {
                queue.add(subject);
                completeSemester[subject] = 1;
            }
        }

        while (!queue.isEmpty()) {
            Integer subject = queue.poll();

            for (Integer nextSubject : adjacencyList[subject]) {
                inDegree[nextSubject]--;

                if (inDegree[nextSubject] == 0) {
                    completeSemester[nextSubject] = completeSemester[subject] + 1;
                    queue.add(nextSubject);
                }
            }
        }

        for (int subject = 1; subject <= numberOfSubject; subject++) {
            sb.append(completeSemester[subject]).append(" ");
        }
    }

    private static void output() {
        System.out.println(sb);
    }

}

0개의 댓글