BOJ

백준 2252 - 줄 세우기

yanJuicy 2022. 2. 22. 01:56
반응형

문제

 

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

 

2252번: 줄 세우기

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

www.acmicpc.net

 

 

풀이

 

위상 정렬을 이용하면 간단히 풀 수 있는 문제이다. 

https://terms.naver.com/entry.nhn?docId=3579618&cid=59086&categoryId=59093

 

위상 정렬 알고리즘

우리가 일상생활에서 하는 모든 행동은 순서가 정해져있다. 외출을 하려고 신발을 신기 위해선 먼저 양말 먼저 신어야 한다. 신발부터 신고 양말을 신을 수는 없다. 라면, 떡볶이 등 음식을 만들 때도 각각에 맞는 조리법이 있다. 우리는 조리법에 나와 있는 순서를 따라야 맛있게 만들 수 있다. 또한 대학에서의 선수과목도 예로 들 수 있다. 대학에서 수강 신청할 때를 생각해보자. 다양한 과목들을 살펴보면서 자신이 듣고 싶은 과목을 찾아볼 것이다. 하지만 대학에서

terms.naver.com

 

앞에 나온 번호가 뒤에 나온 번호보다 앞서 있어야 한다. 방향 그래프를 이용해서 간선 정보를 저장하고, 정점의 진입 차수를 알기 위해 income 배열을 사용해서 진입 차수를 저장한다. 진입 차수가 증가할수록 키가 큰 학생이 되므로 순서상 뒤에 배치되야 한다. 따라서 진입 차수가 0인 정점들은 키가 제일 작은 집단이 된다. 

 

1. 진입 차수가 0인 정점들을 큐에 저장하고 순서대로 꺼내면서 출력을 한다.

2. 진입 차수가 0인 정점들과 연결된 정점의 진입 차수를 1 감소 시킨다.

3. 큐가 빌 때까지 1번과 2번을 반복한다.

 

 

코드

c++

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
#include <iostream>
#include <vector>
#include <queue>
 
using namespace std;
 
int N, M;
int from, to;
vector<int> graph[32001];
int income[32001];
queue<int> order;
 
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
 
    cin >> N >> M;
 
    for (int i = 0; i < M; i++)
    {
        cin >> from >> to;
        graph[from].push_back(to);
        income[to]++;
    }
    
    for (int i = 1; i <= N; i++)
        if (!income[i]) order.push(i);
 
    while (!order.empty())
    {
        int point = order.front(); order.pop();
        cout << point << ' ';
        for (int i = 0; i < graph[point].size(); i++)
        {
            income[graph[point][i]]--;
            if (!income[graph[point][i]]) order.push(graph[point][i]);
        }
    }
 
    return 0;
}
 
cs

 

java

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {

    static int n, m;
    static ArrayList<ArrayList<Integer>> list = new ArrayList<>();
    static int[] inputDegree;
    static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) {
        input();
        solve();
    }

    private static void solve() {
        Queue<Integer> q = new LinkedList<>();

        for (int i=1; i<=n; i++) {
            if (inputDegree[i] == 0)
                q.offer(i);
        }

        while (!q.isEmpty()) {
            int cur = q.poll();
            sb.append(cur).append(" ");

            for (int next : list.get(cur)) {
                inputDegree[next]--;
                if (inputDegree[next] == 0)
                    q.offer(next);
            }
        }

        System.out.println(sb.toString());
    }

    private static void input() {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
        inputDegree = new int[n + 1];

        for (int i=0; i<=n; i++) {
            list.add(new ArrayList<>());
        }

        for (int i=0; i<m; i++) {
            int a = sc.nextInt();
            int b = sc.nextInt();
            inputDegree[b]++;
            list.get(a).add(b);
        }

        sc.close();
    }
}

 

반응형

'BOJ' 카테고리의 다른 글

백준 - 랜선 자르기  (0) 2022.02.28
백준 9095 - 1, 2, 3 더하기  (0) 2022.02.26
백준 11725 - 트리의 부모 찾기  (0) 2022.02.17
백준 10816 - 숫자 카드 2  (0) 2022.02.05
백준 7795 - 먹을 것인가 먹힐 것인가  (0) 2022.02.03