선수과목 (Prerequisite) 성공
시간 제한메모리 제한제출정답맞힌 사람정답 비율
5 초 | 256 MB | 1714 | 1141 | 872 | 66.413% |
문제
올해 Z대학 컴퓨터공학부에 새로 입학한 민욱이는 학부에 개설된 모든 전공과목을 듣고 졸업하려는 원대한 목표를 세웠다. 어떤 과목들은 선수과목이 있어 해당되는 모든 과목을 먼저 이수해야만 해당 과목을 이수할 수 있게 되어 있다. 공학인증을 포기할 수 없는 불쌍한 민욱이는 선수과목 조건을 반드시 지켜야만 한다. 민욱이는 선수과목 조건을 지킬 경우 각각의 전공과목을 언제 이수할 수 있는지 궁금해졌다. 계산을 편리하게 하기 위해 아래와 같이 조건을 간소화하여 계산하기로 하였다.
- 한 학기에 들을 수 있는 과목 수에는 제한이 없다.
- 모든 과목은 매 학기 항상 개설된다.
모든 과목에 대해 각 과목을 이수하려면 최소 몇 학기가 걸리는지 계산하는 프로그램을 작성하여라.
입력
첫 번째 줄에 과목의 수 N(1≤N≤1000)과 선수 조건의 수 M(0≤M≤500000)이 주어진다. 선수과목 조건은 M개의 줄에 걸쳐 한 줄에 정수 A B 형태로 주어진다. A번 과목이 B번 과목의 선수과목이다. A<B인 입력만 주어진다. (1≤A<B≤N)
출력
1번 과목부터 N번 과목까지 차례대로 최소 몇 학기에 이수할 수 있는지를 한 줄에 공백으로 구분하여 출력한다.
위상정렬문제는 처음 풀어봐서
https://github.com/ndb796/python-for-coding-test/blob/master/10/6.py
이코테 파이썬 코드를 템플릿처럼 사용해서 이 문제에 맞게 바꾸어 풀었습니다.
answer 리스트에는 queue를 pop할때 값을 넣어주었습니다.
from collections import deque
import sys
input = sys.stdin.readline
# 노드의 개수와 간선의 개수를 입력 받기
v, e = map(int, input().split())
# 모든 노드에 대한 진입차수는 0으로 초기화
indegree = [0] * (v + 1)
# 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화
graph = [[] for i in range(v + 1)]
# 해당 노드의 수강학기를 담기위한 리스트
answer = [0]*(v+1)
# 방향 그래프의 모든 간선 정보를 입력 받기
for _ in range(e):
a, b = map(int, input().split())
graph[a].append(b) # 정점 A에서 B로 이동 가능
# 진입 차수를 1 증가
indegree[b] += 1
q = deque() # 큐 기능을 위한 deque 라이브러리 사용
# 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입
semester = 1
for i in range(1, v + 1):
if indegree[i] == 0:
q.append((i,1))
# 큐가 빌 때까지 반복
while len(q):
# 큐에서 원소 꺼내기
now,semester = q.popleft()
answer[now]=semester
# 해당 원소와 연결된 노드들의 진입차수에서 1 빼기
for i in graph[now]:
indegree[i] -= 1
# 새롭게 진입차수가 0이 되는 노드를 큐에 삽입
if indegree[i] == 0:
q.append((i,semester+1))
# 위상 정렬을 수행한 결과 출력
for i in range(1,len(answer)):
print(f'{answer[i]} ',end="")
answer 리스트에는 queue를 pop할때 값을 넣어주었습니다.
'알고리즘 공부 > 미분류' 카테고리의 다른 글
백준 14888번 파이썬 (0) | 2022.02.09 |
---|---|
백준 꽃길 14620번 파이썬 (0) | 2022.02.09 |
bfs dfs (0) | 2022.01.14 |
프로그래머스 뉴스 클러스터링 (0) | 2022.01.14 |
파이썬 deep copy (0) | 2022.01.12 |