

과자와 사탕을 싣고서~
from collections import deque, defaultdict
import sys
input = sys.stdin.readline
N = int(input())
M = int(input())
graph = [[] for _ in range(N + 1)]
indegree = [0] * (N + 1)
queue = deque()
for _ in range(M):
a, b, k = map(int, input().split())
# a를 만드는 데, b가 k개 필요함
# b -> a로 향하는 간선
graph[b].append((a, k))
indegree[a] += 1
a를 만들 때 b가 필요하다...라는 뜻입니다k개) 역시 함께 저장합니다# how_many의 i번째 인덱스: i번 부품을 만들 때 필요한 기본부품을 나타내는 딕셔너리
# 딕셔너리는 {기본부품1: a개, 기본부품2: b개} 형태
how_many = [defaultdict(int) for _ in range(N + 1)]
how_many 리스트로 관리합니다how_many[i]는, i번 부품을 만들 때 각 기본부품이 몇 개 필요한지를 나타내는 딕셔너리입니다defaultdict(int)를 사용합니다# 맨 처음 진입차수가 0인 노드 (기본 부품)를 큐에 넣기
# 이때 기본 부품의 딕셔너리는 {자기 자신: 1개}
for i in range(1, N + 1):
if indegree[i] == 0:
queue.append(i)
how_many[i][i] = 1
1번 부품의 딕셔너리 how_many[1]은, {1: 1}로 설정합니다
# 위상 정렬
while queue:
x = queue.popleft()
for y, count in graph[x]:
# 노드 x에서 y로 향하는 간선을 없앨 때마다,
indegree[y] -= 1
# y를 만들 때 필요한 부품 수를 딕셔너리에 갱신
for b in how_many[x]:
# (x를 만들 때 필요한 부품 수) * (필요한 부품 x의 수)
how_many[y][b] += how_many[x][b] * count
if indegree[y] == 0:
queue.append(y)
x에서 y로 향하는 간선을 제거할 때...y를 만들 때 count개의 부품 x가 필요하다고 합시다y의 딕셔너리를 갱신해 줍니다.x의 딕셔너리에서 필요한 각 기본부품별 개수를 확인하고count로 곱해, y의 딕셔너리에 더해 주면 됩니다y의 딕셔너리에 키가 없어도 바로 더해 줘도 됩니다. 없는 키로 접근하면 0의 값을 반환하는 defaultdict 덕분임for i in range(1, N + 1):
result = how_many[N][i]
if result != 0:
print(i, result)
defaultdict는 없는 키에 접근하면 바로 0을 반환합니다result != 0인 경우만 출력하면 되겠죠from collections import deque, defaultdict
import sys
input = sys.stdin.readline
N = int(input())
M = int(input())
graph = [[] for _ in range(N + 1)]
indegree = [0] * (N + 1)
queue = deque()
for _ in range(M):
x, y, k = map(int, input().split())
# x를 만드는 데, y가 k개 필요함
# y -> x로 향하는 간선
graph[y].append((x, k))
indegree[x] += 1
# how_many의 i번째 인덱스: i번 부품을 만들 때 필요한 기본부품을 나타내는 딕셔너리
# 딕셔너리는 {기본부품1: a개, 기본부품2: b개} 형태
how_many = [defaultdict(int) for _ in range(N + 1)]
# 맨 처음 진입차수가 0인 노드 (기본 부품)를 큐에 넣기
# 이때 기본 부품의 딕셔너리는 {자기 자신: 1개}
for i in range(1, N + 1):
if indegree[i] == 0:
queue.append(i)
how_many[i][i] = 1
# 위상 정렬
while queue:
x = queue.popleft()
for y, count in graph[x]:
# 노드 x에서 y로 향하는 간선을 없앨 때마다,
indegree[y] -= 1
# y를 만들 때 필요한 부품 수를 딕셔너리에 갱신
for b in how_many[x]:
# (x를 만들 때 필요한 부품 수) * (필요한 부품 x의 수)
how_many[y][b] += how_many[x][b] * count
if indegree[y] == 0:
queue.append(y)
for i in range(1, N + 1):
result = how_many[N][i]
if result != 0:
print(i, result)
# y를 만들 때 필요한 부품 수를 딕셔너리에 갱신
for b in how_many[x]:
# (x를 만들 때 필요한 부품 수) * (필요한 부품 x의 수)
how_many[y][b] += how_many[x][b] * count
defaultdict를 써라.