백준 2252 파이썬 문제풀이
- CS/BOJ
- 2021. 9. 5.
문제
N명의 학생들을 키 순서대로 줄을 세우려고 한다. 각 학생의 키를 직접 재서 정렬하면 간단하겠지만, 마땅한 방법이 없어서 두 학생의 키를 비교하는 방법을 사용하기로 하였다. 그나마도 모든 학생들을 다 비교해 본 것이 아니고, 일부 학생들의 키만을 비교해 보았다.
일부 학생들의 키를 비교한 결과가 주어졌을 때, 줄을 세우는 프로그램을 작성하시오.
입력
첫째 줄에 N(1 ≤ N ≤ 32,000), M(1 ≤ M ≤ 100,000)이 주어진다. M은 키를 비교한 회수이다. 다음 M개의 줄에는 키를 비교한 두 학생의 번호 A, B가 주어진다. 이는 학생 A가 학생 B의 앞에 서야 한다는 의미이다.
학생들의 번호는 1번부터 N번이다.
출력
첫째 줄에 학생들을 키 순서대로 줄을 세운 결과를 출력한다. 답이 여러 가지인 경우에는 아무거나 출력한다.
문제 풀이
문제에서 주어진 학생들의 키 순서는 그래프로 표현이 가능하다. 또한, 키는 항상 한 방향이기 때문에 내부에 사이클이 발생하지 않는다. 또한 출력 마지막에 '답이 여러가지인 경우에는 아무거나 출력한다'라는 문구가 있기 때문에 해당 문제를 풀 때 위상정렬을 사용할 수 있다.
아래 로직으로 위상정렬을 사용한다.
- 입력을 받을 때, 진입차수 테이블을 만들고 진입차수 테이블을 기록해준다.
- BFS를 시작한다. BFS는 아래 과정으로 접근한다.
2-1. 집입차수가 0인 값을 모두 que에 넣는다.
2-2. 현재 노드에서 살펴봤을 때, 갈 수 있는 다음 노드로 간다. 이 때, 진입 차수 테이블에서 다음 노드에 대한 값을 1을 빼준다.
2-3. 만약 다음 노드가 진입 차수가 0이라면 que에 넣어준다. - 1-2 과정을 que가 빌 때까지 반복해준다.
- 정답을 출력한다.
import sys
from collections import deque
#위상정렬 with BFS
def bfs(v, my_list) :
answer = []
que = deque()
for idx in range(1,len(v)) :
if v[idx] == 0 :
que.append(idx)
while que :
now = que.popleft()
answer.append(now)
for next_idx in my_list[now] :
v[next_idx] -= 1
if v[next_idx] == 0 :
que.append(next_idx)
print(' '.join(map(str,answer)))
#변수 입력
n, m = map(int,sys.stdin.readline().split())
my_list = [[] for _ in range(n + 1)]
#진입차수 테이블 생성
v = [0 for _ in range(n + 1)]
v[0] = 1
for _ in range(m) :
a,b = map(int,sys.stdin.readline().split())
my_list[a].append(b)
v[b] += 1
bfs(v, my_list)
'CS > BOJ' 카테고리의 다른 글
백준 4991번 파이썬 문제풀이 (0) | 2021.09.05 |
---|---|
백준 14442번 파이썬 문제풀이 (0) | 2021.09.05 |
백준 2776번 파이썬 문제 풀이 (0) | 2021.09.05 |
백준 1072번 파이썬 문제풀이 (0) | 2021.09.05 |
백준 1654번 파이썬 문제풀이 (0) | 2021.09.05 |