본문 바로가기

CodingTEST

[백준 2252] 줄 세우기 (JAVA)

반응형

백준 2252번 문제 - 줄 세우기

 

2252번: 줄 세우기

첫째 줄에 N(1 ≤ N ≤ 32,000), M(1 ≤ M ≤ 100,000)이 주어진다. M은 키를 비교한 회수이다. 다음 M개의 줄에는 키를 비교한 두 학생의 번호 A, B가 주어진다. 이는 학생 A가 학생 B의 앞에 서야 한다는 의

www.acmicpc.net


문제 분석

 

 

  • N(학생 수), M(비교 횟수) 입력
  • M번의 비교 입력 : a b 입력 - a가 b의 앞에 와야한다
  • 이를 토대로 학생들 나열 순서에 맞춰 출력해라

해결 키 포인트

 

  • 위상 정렬 개념 이해

위상 정렬

 사이클이 없는 방향 그래프에서 노드 순서를 찾는 알고리즘이다.

 

위상 정렬에서는 항상 유일한 값으로 정렬되지 않는다. 
또한 사이클이 존재하면 노드 간의 순서를 명확하게 정의할 수 없으므로 위상 정렬을 적용 할 수 없다.

 

알고리즘

 

1. 자신이 가르키는 에지(노드)들을 ArrayList로 제작해 구현한다.

1 ➡️ 2, 3

2 ➡️ 4, 5

3 ➡️ 4

4 ➡️ 5

5

 

2. 진입 차수 배열을 구현한다. 진입 차수는 자기 자신을 가리키는 에지의 개수이다.

1 : 0

2 : 1

3 : 1

4 : 2

5 : 2

 

3. 진입 차수 배열에서 진입차수가 0인 노드를 선택하고 선택된 노드를 정렬 배열에 저장한다.
0인 노드 ➡️ 1

 

4. 그 후 인접 리스트에서 선택된 노드가 가리키는 노드들의 진입 차수를 1씩 뺀다.

1 : 0

2 : 1 - 1 : 0

3 : 1 - 1 : 0

4 : 2

5 : 2

 


코드

 

import java.io.*;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class Main {
    public static void main(String [] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        // N,M 입력
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        // 자신으로 올 수 있는 화살표의 개수를 알아낼 수 있는 변수
        int [] inDegree = new int[N];

        // N개의 수의 연관된 값들의 변수
        ArrayList<Integer> [] lists = new ArrayList[N];
        for(int i=0;i<N;i++)
            lists[i] = new ArrayList<>();

        // M개의 키 비교 결과 입력 ( a b : a가 b보다 앞으로 )
        for(int i=0;i<M;i++) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken())-1;
            int b = Integer.parseInt(st.nextToken())-1;

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

        for(int i=0;i<N;i++) {
            // inDegree가 0인 수 알아내서 출력
            int index = getZeroDegree(inDegree);
            bw.write(index+1 + " ");
            // 해당 값으로 연결될 수 잇는 수의 inDegree 다 -1 처리
            ArrayList<Integer> list = lists[index];
            for(int j=0;j<list.size();j++) {
                inDegree[list.get(j)]--;
            }
            inDegree[index]--;
        }

        bw.flush();
        bw.close();
    }

    public static int getZeroDegree(int [] inDegree) {
        int result = 0;
        for (int i = 0; i < inDegree.length; i++) {
            if(inDegree[i] == 0) {
                result = i;
                break;
            }
        }
        return result;
    }
}
 
 
반응형

'CodingTEST' 카테고리의 다른 글

[백준 4358] 생태학 (JAVA)  (0) 2023.09.19
[백준 1516] 게임 개발 (JAVA)  (0) 2023.08.29
[백준 1043] 거짓말 (JAVA)  (1) 2023.08.27
[백준 1976] 여행 가자 (JAVA)  (0) 2023.08.26
[백준 1717] 집합의 표현 (JAVA)  (2) 2023.08.26