728x90
http://www.acmicpc.net/problem/1766
# 조건
- 민오는 1번부터 N번까지 총 N개의 문제로 되어 있는 문제집을 풀려고 한다.
- 문제는 난이도 순서로 출제되어 있다.
- 즉 1번 문제가 가장 쉬운 문제이고 N번 문제가 가장 어려운 문제가 된다.
- 어떤 문제부터 풀까 고민하면서 문제를 훑어보던 민오는, 몇몇 문제들 사이에는 '먼저 푸는 것이 좋은 문제'가 있다는 것을 알게 되었다.
- 예를 들어 1번 문제를 풀고 나면 4번 문제가 쉽게 풀린다거나 하는 식이다. 민오는 다음의 세 가지 조건에 따라 문제를 풀 순서를 정하기로 하였다.
- N개의 문제는 모두 풀어야 한다.
- 먼저 푸는 것이 좋은 문제가 있는 문제는, 먼저 푸는 것이 좋은 문제를 반드시 먼저 풀어야 한다.
- 가능하면 쉬운 문제부터 풀어야 한다.
- 예를 들어서 네 개의 문제가 있다고 하자. 4번 문제는 2번 문제보다 먼저 푸는 것이 좋고, 3번 문제는 1번 문제보다 먼저 푸는 것이 좋다고 하자.
- 만일 4-3-2-1의 순서로 문제를 풀게 되면 조건 1과 조건 2를 만족한다.
- 하지만 조건 3을 만족하지 않는다. 4보다 3을 충분히 먼저 풀 수 있기 때문이다. 따라서 조건 3을 만족하는 문제를 풀 순서는 3-1-4-2가 된다.
- 문제의 개수와 먼저 푸는 것이 좋은 문제에 대한 정보가 주어졌을 때, 주어진 조건을 만족하면서 민오가 풀 문제의 순서를 결정해 주는 프로그램을 작성하시오.
# 접근 방법
- heapq를 사용하여 먼저 푸는 것이 좋은 문제 순으로 넣어준다.
- 또한 quest 리스트를 N+1 의 크기로 만들어준 후, 먼저 푸는 것이 좋은 문제로 나올 때 +1을 해준다.
- 즉, 위상 정렬을 이용하여 풀어준다.
- 위상 정렬이란, 사이클이 없는 방향그래프에서 순서가 정해져 있는 작업을 차례로 수행할 때, 순서를 정해주는 알고리즘이다.
- 각 문제의 진입차수를 기록해두고 우선 순위 큐를 이용하여 넣어준다.
- 문제를 풀 때는 진입 차수를 -1씩 해준다.
import sys
from heapq import heappush, heappop
sys.stdin = open('input.txt')
input = sys.stdin.readline
N, M = map(int, input().split())
quest = [[] for _ in range(N+1)]
degree = [0 for _ in range(N+1)]
result = []
q = []
for _ in range(M):
a, b = map(int, input().split())
quest[a].append(b)
degree[b] += 1
for i in range(1, N+1):
if degree[i] == 0:
heappush(q, i)
while q:
c = heappop(q)
result.append(c)
for k in quest[c]:
degree[k] -= 1
if degree[k] == 0:
heappush(q, k)
print(*result)
728x90
'ALGORITHM > 정렬, 탐색,구현' 카테고리의 다른 글
[백준 1806번] 파이썬 - 부분합 (0) | 2023.01.17 |
---|---|
[백준 1005번] 파이썬 - ACM Craft (0) | 2023.01.05 |
[백준 1484번] 파이썬 - 다이어트 (1) | 2022.12.03 |
[백준 5525번] 파이썬 - IOIOI (0) | 2022.10.12 |
[백준 17276번] 파이썬 - 배열 돌리기 (0) | 2022.10.10 |