문제 출처 : https://www.acmicpc.net/problem/14567
문제
올해 Z대학 컴퓨터공학부에 새로 입학한 민욱이는 학부에 개설된 모든 전공과목을 듣고 졸업하려는 원대한 목표를 세웠다. 어떤 과목들은 선수과목이 있어 해당되는 모든 과목을 먼저 이수해야만 해당 과목을 이수할 수 있게 되어 있다. 공학인증을 포기할 수 없는 불쌍한 민욱이는 선수과목 조건을 반드시 지켜야만 한다. 민욱이는 선수과목 조건을 지킬 경우 각각의 전공과목을 언제 이수할 수 있는지 궁금해졌다. 계산을 편리하게 하기 위해 아래와 같이 조건을 간소화하여 계산하기로 하였다.
- 한 학기에 들을 수 있는 과목 수에는 제한이 없다.
- 모든 과목은 매 학기 항상 개설된다.
모든 과목에 대해 각 과목을 이수하려면 최소 몇 학기가 걸리는지 계산하는 프로그램을 작성하여라.
입력
첫 번째 줄에 과목의 수 N(1≤N≤1000)과 선수 조건의 수 M(0≤M≤500000)이 주어진다. 선수과목 조건은 M개의 줄에 걸쳐 한 줄에 정수 A B 형태로 주어진다. A번 과목이 B번 과목의 선수과목이다. A<B인 입력만 주어진다. (1≤A<B≤N)
출력
1번 과목부터 N번 과목까지 차례대로 최소 몇 학기에 이수할 수 있는지를 한 줄에 공백으로 구분하여 출력한다.
힌트
3개의 과목이 있고, 2번 과목을 이수하기 위해서는 1번 과목을 이수해야 하고, 3번 과목을 이수하기 위해서는 2번 과목을 이수해야 한다.
알고리즘 분류
풀이
2021.07.24 - [알고리즘] - [알고리즘] Graph-위상 정렬(Topological Sort)
2021.03.24 - [알고리즘 문제 풀이/백준] - 백준 2252 줄 세우기 c++, Kotlin (위상정렬)
위상 정렬을 할 줄 알면 바로 풀 수 있는 위상 정렬 기본 문제이다.
위상 정렬에 대한 내용은 위에 글을 읽어보면 되고,
입력으로 주어진 A, B는 B 수업을 듣기 위해선 A 수업을 들어야 하므로 inDegree[B]++, edge[A].add(B)를 해주면 된다.
이후 모든 과목에 대해서 가장 빠르게 들을 수 있는 학기를 출력해야 하므로, 어떠한 수업 A가 inDegree가 0이 된다면(선수 과목을 모두 듣는다면) 그 시점을 바로 출력해야 하는데, 이를 turn으로 표현하였다.
코드
import java.util.*
val br = System.`in`.bufferedReader()
lateinit var inDegree: IntArray
lateinit var edge: Array<ArrayList<Int>>
lateinit var answer: IntArray
fun topologicalSort(n: Int){
val q: Queue<Int> = LinkedList()
for(i in 1 .. n){
if(inDegree[i]==0){
q.add(i)
answer[i]=1
}
}
var turn = 2
while(q.isNotEmpty()){
val size = q.size
for(i in 0 until size) {
val cur = q.poll()
for (next in edge[cur]) {
if (--inDegree[next] == 0) {
q.add(next)
answer[next] = turn
}
}
}
turn++
}
}
fun main() = with(System.out.bufferedWriter()){
//input
val (n,m) = br.readLine().split(' ').map{it.toInt()}
inDegree = IntArray(n+1)
edge = Array(n+1){ ArrayList() }
answer = IntArray(n+1)
for(i in 0 until m){
val (from, to) =br.readLine().split(' ').map{it.toInt()}
inDegree[to]++
edge[from].add(to)
}
//solve
topologicalSort(n)
//output
for(i in 1 .. n){
print("${answer[i]} ")
}
close()
}
'알고리즘 문제 풀이 > 백준' 카테고리의 다른 글
백준 15787 기차가 어둠을 헤치고 은하수를 Kotlin (비트마스킹) (0) | 2022.04.07 |
---|---|
백준 13913 숨바꼭질 4 Kotlin (bfs) (0) | 2022.04.05 |
백준 17609 회문 Kotlin (투 포인터) (0) | 2022.04.03 |
백준 1174 줄어드는 수 Kotlin (백트래킹) (0) | 2022.04.02 |
백준 15681 트리와 쿼리 Kotlin (dp) (0) | 2022.04.01 |
댓글