forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
minimum-cost-of-a-path-with-special-roads.py
72 lines (67 loc) · 2.49 KB
/
minimum-cost-of-a-path-with-special-roads.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
69
70
71
72
# Time: O(n^2)
# Space: O(n^2)
import collections
# dijkstra's algorithm in a complete graph (no heap required)
class Solution(object):
def minimumCost(self, start, target, specialRoads):
"""
:type start: List[int]
:type target: List[int]
:type specialRoads: List[List[int]]
:rtype: int
"""
start, target = tuple(start), tuple(target)
adj = collections.defaultdict(list, {target:[]})
for x1, y1, x2, y2, c in specialRoads:
adj[x1, y1].append((x2, y2, c))
dist = {start:0}
lookup = set()
while len(lookup) != len(dist):
d, x1, y1 = min((dist[x1, y1], x1, y1) for x1, y1 in dist.iterkeys() if (x1, y1) not in lookup)
lookup.add((x1, y1))
if (x1, y1) == target:
return d
for x2, y2, c in adj[x1, y1]:
if not ((x2, y2) not in dist or dist[x2, y2] > d+c):
continue
dist[x2, y2] = d+c
for x2, y2 in adj.iterkeys():
if not ((x2, y2) not in dist or dist[x2, y2] > d+abs(x2-x1)+abs(y2-y1)):
continue
dist[x2, y2] = d+abs(x2-x1)+abs(y2-y1)
# Time: O(n^2 * logn)
# Space: O(n^2)
import collections
import heapq
# dijkstra's algorithm
class Solution2(object):
def minimumCost(self, start, target, specialRoads):
"""
:type start: List[int]
:type target: List[int]
:type specialRoads: List[List[int]]
:rtype: int
"""
start, target = tuple(start), tuple(target)
adj = collections.defaultdict(list, {target:[]})
for x1, y1, x2, y2, c in specialRoads:
adj[x1, y1].append((x2, y2, c))
min_heap = [(0, start)]
dist = {start:0}
while min_heap:
d, (x1, y1) = heapq.heappop(min_heap)
if d > dist[x1, y1]:
continue
if (x1, y1) == target:
return d
for x2, y2, c in adj[x1, y1]:
if not ((x2, y2) not in dist or dist[x2, y2] > d+c):
continue
dist[x2, y2] = d+c
heapq.heappush(min_heap, (dist[x2, y2], (x2, y2)))
for x2, y2 in adj.iterkeys():
if not ((x2, y2) not in dist or dist[x2, y2] > d+abs(x2-x1)+abs(y2-y1)):
continue
dist[x2, y2] = d+abs(x2-x1)+abs(y2-y1)
heapq.heappush(min_heap, (dist[x2, y2], (x2, y2)))
return -1