-
백준 1766 - 문제집 (Python)BOJ PS/Python 2023. 1. 13. 15:56
https://acmicpc.net/problem/1766
1766번: 문제집
첫째 줄에 문제의 수 N(1 ≤ N ≤ 32,000)과 먼저 푸는 것이 좋은 문제에 대한 정보의 개수 M(1 ≤ M ≤ 100,000)이 주어진다. 둘째 줄부터 M개의 줄에 걸쳐 두 정수의 순서쌍 A,B가 빈칸을 사이에 두고 주
www.acmicpc.net
위상 정렬의 개념을 모르고 풀어서 한참을 고생한 문제였다.
처음 풀이는 이랬다.
import sys, heapq from collections import deque input=sys.stdin.readline n,m=map(int,input().split()) ps=[] visited=[False]*(n+1) for _ in range(m): heapq.heappush(ps,deque(list(map(int,input().split())))) while ps: cur=heapq.heappop(ps) if cur: temp=cur.popleft() if not visited[temp]: print(temp,end=" ") visited[temp]=True if cur: heapq.heappush(ps,cur)즉 단순히 생각해서 먼저 풀어야 하는 문제와 후에 풀어야 하는 문제의 리스트를 만들고, heap을 이용해 먼저 풀어야 하는 문제의 번호가 낮을수록 먼저 빼준다는 생각이었으나, 이런 방식으로는 문제를 풀 수 없어 위상정렬을 공부했다.
위상정렬은 사이클이 없는 그래프에서만 가능한 정렬로, 딱 이 문제처럼 어떤 노드를 방문하기 위해서 그 전 노드를 탐색해야만 하는 경우 적용하는 방법이다.
골자는 굉장히 간단한데, 이 문제 식대로 해석하자면 다음과 같다.
우선 선수과목과 후순위 과목을 입력받아 후순위 과목의 우선순위에 +1을 하는 식으로 노드를 정리한다.
그 후, 선수과목이 없는 과목들로 heap을 만들고,
1. heap에서 요소를 pop한다.
2. 그 문제를 선수과목으로 하는 과목들의 우선순위에 -1을 해준다.
3. 우선 순위가 0이 된 문제는 heap에 push 한다.
이 과정을 반복해주면 된다.
이때 '우선순위'를 우리는 진입 차수(in-degree)라고 한다.
이렇게 작성한 코드는 다음과 같다.
import heapq num_problem, num_compare = map(int, input().split()) problem_list = [[] for i in range(num_problem + 1)] indegree = [0 for i in range(num_problem + 1)] heap = [] result = [] for i in range(num_compare): first, next = map(int, input().split()) problem_list[first].append(next) #선수과목과 후순위 과목 사이 간선을 만든다. indegree[next] += 1 #후순위 과목의 진입 차수를 올린다. for i in range(1, num_problem + 1): if indegree[i] == 0: heapq.heappush(heap, i) #진입 차수가 0인 과목을 heap에 넣고 while heap: #heap 내에 과목이 있는 동안 temp = heapq.heappop(heap) #가장 과목 번호 수가 적은 것을 pop한다. result.append(temp) for j in problem_list[temp]: #만들어두었던 선수과목-후순위 과목 그래프를 돌며 indegree[j] -= 1 #후순위 과목의 진입차수를 줄이고 if indegree[j] == 0: #진입 차수가 0이면 heapq.heappush(heap, j) #그 과목 또한 heap에 넣어준다. for i in result: print(i, end=' ')새로웠고, 여러 모로 쓸 곳이 있겠다는 생각이 든 개념이었다.
'BOJ PS > Python' 카테고리의 다른 글
백준 1687 - 행렬 찾기 (Python) (0) 2023.01.13 백준 16209 - 수열 섞기 (Python) (0) 2023.01.13 백준 7579 - 앱 (Python) (0) 2023.01.13 백준 12100 - 2048 (Easy) (Python) (0) 2023.01.13 백준 2342 - dance dance revoution (Python) (0) 2022.12.16