-
-
Notifications
You must be signed in to change notification settings - Fork 9k
/
Copy pathSolution.py
68 lines (61 loc) · 1.96 KB
/
Solution.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Node:
__slots__ = ["children", "v"]
def __init__(self):
self.children: List[Node | None] = [None] * 26
self.v = -1
class Solution:
def minimumCost(
self,
source: str,
target: str,
original: List[str],
changed: List[str],
cost: List[int],
) -> int:
m = len(cost)
g = [[inf] * (m << 1) for _ in range(m << 1)]
for i in range(m << 1):
g[i][i] = 0
root = Node()
idx = 0
def insert(w: str) -> int:
node = root
for c in w:
i = ord(c) - ord("a")
if node.children[i] is None:
node.children[i] = Node()
node = node.children[i]
if node.v < 0:
nonlocal idx
node.v = idx
idx += 1
return node.v
@cache
def dfs(i: int) -> int:
if i >= len(source):
return 0
res = dfs(i + 1) if source[i] == target[i] else inf
p = q = root
for j in range(i, len(source)):
p = p.children[ord(source[j]) - ord("a")]
q = q.children[ord(target[j]) - ord("a")]
if p is None or q is None:
break
if p.v < 0 or q.v < 0:
continue
res = min(res, dfs(j + 1) + g[p.v][q.v])
return res
for x, y, z in zip(original, changed, cost):
x = insert(x)
y = insert(y)
g[x][y] = min(g[x][y], z)
for k in range(idx):
for i in range(idx):
if g[i][k] >= inf:
continue
for j in range(idx):
# g[i][j] = min(g[i][j], g[i][k] + g[k][j])
if g[i][k] + g[k][j] < g[i][j]:
g[i][j] = g[i][k] + g[k][j]
ans = dfs(0)
return -1 if ans >= inf else ans