올해 Z대학 컴퓨터공학부에 새로 입학한 민욱이는 학부에 개설된 모든 전공과목을 듣고 졸업하려는 원대한 목표를 세웠다. 어떤 과목들은 선수과목이 있어 해당되는 모든 과목을 먼저 이수해야만 해당 과목을 이수할 수 있게 되어 있다. 공학인증을 포기할 수 없는 불쌍한 민욱이는 선수과목 조건을 반드시 지켜야만 한다. 민욱이는 선수과목 조건을 지킬 경우 각각의 전공과목을 언제 이수할 수 있는지 궁금해졌다. 계산을 편리하게 하기 위해 아래와 같이 조건을 간소화하여 계산하기로 하였다.
- 한 학기에 들을 수 있는 과목 수에는 제한이 없다.
- 모든 과목은 매 학기 항상 개설된다.
모든 과목에 대해 각 과목을 이수하려면 최소 몇 학기가 걸리는지 계산하는 프로그램을 작성하여라.
첫 번째 줄에 과목의 수 N(1≤N≤1000)과 선수 조건의 수 M(0≤M≤500000)이 주어진다. 선수과목 조건은 M개의 줄에 걸쳐 한 줄에 정수 A B 형태로 주어진다. A번 과목이 B번 과목의 선수과목이다. A<B인 입력만 주어진다. (1≤A<B≤N)
1번 과목부터 N번 과목까지 차례대로 최소 몇 학기에 이수할 수 있는지를 한 줄에 공백으로 구분하여 출력한다.
위상정렬(TopologySort)를 사용하여 풀면 된다.
문제에서 최종적으로 모든 과목에 대해 각 과목을 이수하려면 최소 몇 학기가 걸리는지 구하는 것이기 때문에 별도의 클래스 Subject를 선언하여 semester라는 변수를 통해 학기를 저장했다.
또한 각 과목의 최소 학기를 저장하기 위해 result 이름의 배열을 사용하였다.
topologySort() 메서드안에서 큐에 Subject 객체를 넣는 방식으로 구현을 하였고, 진입차수가 0인 것들을 먼저 큐에 넣어주었다. 이때, 해당 객체의 semester 는 0으로 초기화 한다.
큐가 비어질때까지 하나씩 꺼내어 진입차수를 1씩 감소시키고 진입차수가 0일때 해당 인덱스에 해당하는 부분의 값을 큐에서 꺼낸 객체(now에 해당) semester +1를 해준다.
큐에 다시 넣을 때 semester+1를 한 값을 넣어줘야 한다.
import java.util.*;
class Subject {
private int index;
private int semester;
public Subject(int index, int semester) {
this.index = index;
this.semester = semester;
}
public int getIndex() {
return this.index;
}
public int getSemester() {
return this.semester;
}
}
public class Main {
public static int n, m;
public static int[] indegree = new int[500001];
public static ArrayList<ArrayList<Integer>> graph = new ArrayList<ArrayList<Integer>>();
public static int result = 0;
public static void topologySort() {
// 결과 테이블
int[] result = new int[n + 1];
Queue<Subject> q = new LinkedList<>();
for (int i = 1; i <= n; i++) {
if (indegree[i] == 0) {
q.offer(new Subject(i, 0));
}
}
while (!q.isEmpty()) {
Subject now = q.poll();
for (int i = 0; i < graph.get(now.getIndex()).size(); i++) {
indegree[graph.get(now.getIndex()).get(i)] -= 1;
if (indegree[graph.get(now.getIndex()).get(i)] == 0) {
result[graph.get(now.getIndex()).get(i)] = now.getSemester() + 1;
q.offer(new Subject(graph.get(now.getIndex()).get(i), now.getSemester() + 1));
}
}
}
for (int i = 1; i < result.length; i++) {
System.out.print((result[i] + 1) + " ");
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
for (int i = 0; i <= n; i++) {
graph.add(new ArrayList<Integer>());
}
for (int i = 0; i < m; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
graph.get(a).add(b);
indegree[b] += 1;
}
topologySort();
}
}