꾸물꾸물 졔의 개발공부

백준 1766 - 문제집 ( JAVA ) 본문

알고리즘/백준

백준 1766 - 문제집 ( JAVA )

체제 2022. 9. 18. 13:03

출처 - 백준 프로그램

 

1766번: 문제집

첫째 줄에 문제의 수 N(1 ≤ N ≤ 32,000)과 먼저 푸는 것이 좋은 문제에 대한 정보의 개수 M(1 ≤ M ≤ 100,000)이 주어진다. 둘째 줄부터 M개의 줄에 걸쳐 두 정수의 순서쌍 A,B가 빈칸을 사이에 두고 주

www.acmicpc.net


 

 

[Algorithm] 위상정렬(Topology Sort)

위상정렬이란 ? : 순서가 정해져 있는 작업을 차례대로 수행해야 할 때 , 그 순서를 결정해 주기 위해 사용하는 알고리즘 작업의 순서는 '조건'을 통해 그래프의 흐름으로 나타낼 수 있음 . 위상

jiko1456.tistory.com

↑  위상정렬을 이용해서 구현하였다 . 

 

[ 알고리즘

List 를 담은 List 를 생성하였다 . 각 문제에 대하여 '이후에' 풀 수 있는 문제를 담고 있다. 

예를 들어, 문제 1 은 문제 3 이후에 풀 수 있기 때문에 list[3] = {1} 이다. 

 

count 일차원 배열에, 진입차수값을 저장하였다.

  • 선행되어야 할 문제가 있다면, 해당 문제만큼 값 저장 
  • 선행되어야 할 문제가 없다면 , 진입 차수 = 0 

쉬운 문제, 즉 숫자가 작은 문제 먼저 풀어야 하기 때문에 우선순위큐를 이용하였다. 

  1. 진입 차수가 0 인 문제, 즉 선행되어야 할 문제가 없는 것 부터 우선순위큐에 넣는다 ( 3 ,4 ) 
  2. 가장 첫번째의 값을 poll 한다. 우선순위큐에 의해 더 작은 값이 먼저 나온다.
  3. 이후에 풀 수 있는 문제를 담은 list 를 탐색하며, 해당 문제의 진입 차수 값을 -1 한다. 
  4. 진입차수가 0 인 된 문제가 있다면, 선행되어야 할 문제를 다 푼것이므로 큐에 넣는다. 
  5. 반 - 복 

[ 코드 ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import java.util.*;
import java.io.*;
 
public class Solution_BaekJoon_1766_문제집_골드2 {
 
    public static void main(String[] args) throws Exception{
        BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb= new StringBuilder(); 
        StringTokenizer st ;
        
        String s= br.readLine();
        st= new StringTokenizer(s, " ");
        int N= Integer.parseInt(st.nextToken());
        int M= Integer.parseInt(st.nextToken());
        
        List<List<Integer>> list = new ArrayList<List<Integer>>();
        for(int i=0; i<=N; i++) {
            list.add(new ArrayList<Integer>()); 
        }
        
        int[] count = new int[N+1]; //진입차수
        while(M-->0) {
            String s1= br.readLine();
            st= new StringTokenizer(s1, " ");
            
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken()); 
            list.get(a).add(b);
            count[b]++;
        }
    
        PriorityQueue<Integer> que = new PriorityQueue<>(); 
        for(int i=1; i<=N; i++) {
            if(count[i]==0) {
                que.add(i);
                count[i]=-1;
            }
        }
        
        while(!que.isEmpty()) {
            int now = que.poll(); // 더 작은 값 나오겠지 ? 
            sb.append(now).append(" ");
            
            List<Integer> nli = list.get(now);
            if(!nli.isEmpty()) {
                int size = nli.size();
                for(int i=0; i<size; i++) {
                    count[nli.get(i)]--;
                }
            }
            
            for(int i=1; i<=N; i++) {
                if(count[i]==0) {
                    que.add(i);
                    count[i]=-1;
                }
            }
        }
 
        System.out.println(sb);
    }
}
 
cs

끗 !