[백준] #2252 줄 세우기(python)

수영·2022년 11월 13일

백준

목록 보기
77/117
post-thumbnail

📌문제

N명의 학생들을 키 순서대로 줄을 세우려고 한다. 각 학생의 키를 직접 재서 정렬하면 간단하겠지만, 마땅한 방법이 없어서 두 학생의 키를 비교하는 방법을 사용하기로 하였다. 그나마도 모든 학생들을 다 비교해 본 것이 아니고, 일부 학생들의 키만을 비교해 보았다.

일부 학생들의 키를 비교한 결과가 주어졌을 때, 줄을 세우는 프로그램을 작성하시오.

입력

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

학생들의 번호는 1번부터 N번이다.

출력

첫째 줄에 학생들을 앞에서부터 줄을 세운 결과를 출력한다. 답이 여러 가지인 경우에는 아무거나 출력한다.

예제 입력1

3 2
1 3
2 3

예제 출력1

1 2 3

예제 입력2

4 2
4 2
3 1

예제 출력2

4 2 3 1

백준 2252번 문제

💡Idea

일부 학생들에 대해서 키를 비교한 결과를 알고 있고, 그 결과들을 바탕으로 모든 학생들의 키를 정렬해보는 문제입니다.

따라서 이 문제는 위상 정렬(Topological Sort)로 해결할 수 있습니다.

  • 학생 = 정점
  • 학생 A가 학생 B의 앞에 서야 한다는 조건 = 그래프에 존재하는 각 정점들의 선행 순서 조건

단순히 학생들의 키 순서 조건에 따라서 정렬한 결과를 나타내면 되는 문제이므로, 학생들을 위상 정렬 알고리즘을 통해 정렬한 결과를 출력하면 됩니다.

💻코드

  • ⏰ 시간 : 256 ms / 메모리 : 37324 KB
import sys
from collections import deque
input = sys.stdin.readline

N, M = map(int, input().split()) # N : 학생 수, M : 비교한 횟수
graph = [[] for _ in range(N + 1)] # 각 학생들의 뒤에 오는 학생들을 저장
indegree = [0] * (N + 1) # 각 학생들의 앞에 오는 학생들의 수 저장
for _ in range(M):
    a, b = map(int, input().split())
    graph[a].append(b) # 학생 a 뒤에 오는 학생 b
    indegree[b] += 1 # 학생 b 앞에 와야하는 학생의 수 + 1

queue = deque([]) # 큐를 사용한 위상 정렬
for i in range(1, N + 1): # indegree가 0인 학생 찾아 큐 삽입
    if indegree[i] == 0: 
        queue.append(i)
while queue:
    cur = queue.popleft()
    print(cur, end=' ') # 큐에서 나온 순서대로 출력(위상 정렬의 결과)
    for node in graph[cur]: # 현재 학생 뒤에 오는 학생들에 대한 반복문
        indegree[node] -= 1 # indegree 1감소
        if indegree[node] == 0: # indegree가 0이라면 큐 삽입
            queue.append(node)
profile
하고 싶은 건 그냥 죽도록 합니다

0개의 댓글