개발/algorithm
[백준 9470번] Strahler 순서 - python
zzi_on2
2022. 6. 12. 19:24
문제 링크
풀이
- 위상 정렬 응용
- 오랜만에 위상정렬.. 다 까먹었구나
- 위상 정렬 이란 ?
- 방향 그래프의 모든 노드를 방향성에 거스르지 않도록 순서대로 나열하는 것
- 순서가 정해져 있는 일련의 작업을 차례대로 수행햐아 할 때 사용할 수 있는 알고리즘
from collections import deque
def topology_sort():
q = deque()
# 들어오는 최대 레벨, 최대 레벨의 개수
num = [[0,0]] * (m+1)
# 진입 차수 0인 거 큐에 담기
for i in range(1,m+1):
if indegree[i] == 0 :
# 최대 레벨 1, 레벨 1인 노드의 개수 1개
num[i] = [1,1]
q.append(i)
# 순서 번호 저장할 배열
order = [0] * (m+1)
while q :
now = q.popleft()
# 최대 레벨의 개수가 2개 이상이면
if num[now][1] >= 2 :
# 최대 레벨 + 1
order[now] = num[now][0] + 1
# 아니면 최대 레벨과 동일
else :
order[now] = num[now][0]
for i in graph[now]:
# 해당 노드와 연결된 노드들의 진입차수 -1
indegree[i] -= 1
# 최대 레벨 번호 같으면 개수 증가
if num[i][0] == order[now] :
num[i][1] += 1
# 더 크면 갱신
elif num[i][0] < order[now] :
num[i] = [order[now], 1]
# 진입 차수 0 이면 큐에 삽입
if indegree[i] == 0 :
q.append(i)
# 노드 m의 순서 번호 리턴
return order[m]
test = int(input())
for _ in range(test):
# 테스트 케이스 번호, 노드 수, 간선 수
k, m, p = map(int,input().split())
# 모든 노드의 진입차수는 0으로 초기화
indegree = [0] * (m+1)
graph = [ [] for _ in range(m+1)]
for _ in range(p):
a, b = map(int,input().split())
# a에서 b로 이동 가능
graph[a].append(b)
# b의 진입차수 + 1
indegree[b] += 1
print(k, end = " ")
print(topology_sort())