74 lines
1.7 KiB
Python
74 lines
1.7 KiB
Python
import heapq
|
|
def solve(input):
|
|
G = {}
|
|
V = []
|
|
for line in open(input):
|
|
parts = line.split()
|
|
v = parts.pop(0).strip(':')
|
|
V.append(v)
|
|
G[v] = parts
|
|
|
|
sinks = [e for edges in G.values() for e in edges if e not in V]
|
|
V += sinks
|
|
for v in sinks:
|
|
G[v] = []
|
|
|
|
# reversed graph
|
|
R = {}
|
|
for v, E in G.items():
|
|
for e in E:
|
|
R.setdefault(e, []).append(v)
|
|
|
|
# topological sort
|
|
# T is an order of vertices such that each vertex is
|
|
# listed _after_ all the vertices connected to its incoming edges.
|
|
T = []
|
|
seen = set()
|
|
def visit(v):
|
|
if v not in seen:
|
|
seen.add(v)
|
|
for e in R.get(v,()):
|
|
visit(e)
|
|
T.append(v)
|
|
|
|
visit('out')
|
|
#T.reverse()
|
|
#print(T)
|
|
|
|
def paths(start,end):
|
|
Q = [(0,start)]
|
|
seen = set()
|
|
paths = {v:0 for v in V}
|
|
paths[start] = 1
|
|
for v in T:
|
|
if v in seen:
|
|
continue
|
|
seen.add(v)
|
|
for e in G[v]:
|
|
paths[e] += paths[v]
|
|
#print(paths)
|
|
return paths[end]
|
|
|
|
if 'you' in G:
|
|
# Part 1:
|
|
# find all paths from you -> out
|
|
print(paths('you', 'out'))
|
|
|
|
if 'svr' in G:
|
|
# Part 2: find all paths that pass through
|
|
# svr -> fft -> dac -> out, or
|
|
# svr -> dac -> fft -> out.
|
|
sf = paths('svr', 'fft')
|
|
sd = paths('svr', 'dac')
|
|
fd = paths('fft', 'dac')
|
|
df = paths('dac', 'fft')
|
|
do = paths('dac', 'out')
|
|
fo = paths('fft', 'out')
|
|
|
|
print(sf*fd*do + sd*df*fo)
|
|
|
|
|
|
solve("sample")
|
|
solve("sample2")
|
|
solve("input")
|