forked from matthewsamuel95/ACM-ICPC-Algorithms
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDadjacencylist.py
More file actions
159 lines (113 loc) · 3.86 KB
/
Dadjacencylist.py
File metadata and controls
159 lines (113 loc) · 3.86 KB
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# Python program for Dijkstra's shortest path algorithm for adjacency list
# representation of graph
from collections import defaultdict
import sys
class Heap():
def __init__(self):
self.array = []
self.size = 0
self.pos = []
def newMinHeapNode(self, v, dist):
return [v, dist]
# A utility function to swap two nodes
# of min heap. Needed for min heapify
def swapMinHeapNode(self, a, b):
t = self.array[a]
self.array[a] = self.array[b]
self.array[b] = t
def minHeapify(self, idx):
smallest = idx
left = 2 * idx + 1
right = 2 * idx + 2
if left < self.size and self.array[left][1] < self.array[smallest][1]:
smallest = left
if right < self.size and self.array[right][1] \
< self.array[smallest][1]:
smallest = right
if smallest != idx:
# Swap positions
self.pos[self.array[smallest][0]] = idx
self.pos[self.array[idx][0]] = smallest
self.swapMinHeapNode(smallest, idx)
self.minHeapify(smallest)
def extractMin(self):
if self.isEmpty() is True:
return
root = self.array[0]
lastNode = self.array[self.size - 1]
self.array[0] = lastNode
self.pos[lastNode[0]] = 0
self.pos[root[0]] = self.size - 1
self.size -= 1
self.minHeapify(0)
return root
def isEmpty(self):
return True if self.size == 0 else False
def decreaseKey(self, v, dist):
# Get the index of v in heap array
i = self.pos[v]
self.array[i][1] = dist
while i > 0 and self.array[i][1] < self.array[(i - 1) / 2][1]:
# Swap this node with its parent
self.pos[self.array[i][0]] = (i - 1) / 2
self.pos[self.array[(i - 1) / 2][0]] = i
self.swapMinHeapNode(i, (i - 1) / 2)
# move to parent index
i = (i - 1) / 2
# A utility function to check if a given
# vertex 'v' is in min heap or not
def isInMinHeap(self, v):
return self.pos[v] < self.size
def printArr(dist, n):
print("Vertex\tDistance from source")
for i in range(n):
print("%d\t\t%d" % (i, dist[i]))
class Graph():
def __init__(self, V):
self.V = V
self.graph = defaultdict(list)
def addEdge(self, src, dest, weight):
newNode = [dest, weight]
self.graph[src].insert(0, newNode)
newNode = [src, weight]
self.graph[dest].insert(0, newNode)
def dijkstra(self, src):
V = self.V # Get the number of vertices in graph
dist = [] # dist values used to pick minimum
# weight edge in cut
minHeap = Heap()
for v in range(V):
dist.append(sys.maxint)
minHeap.array.append(minHeap.newMinHeapNode(v, dist[v]))
minHeap.pos.append(v)
minHeap.pos[src] = src
dist[src] = 0
minHeap.decreaseKey(src, dist[src])
minHeap.size = V
while minHeap.isEmpty() is False:
newHeapNode = minHeap.extractMin()
u = newHeapNode[0]
for pCrawl in self.graph[u]:
v = pCrawl[0]
if minHeap.isInMinHeap(v) and dist[u] != sys.maxint and \
pCrawl[1] + dist[u] < dist[v]:
dist[v] = pCrawl[1] + dist[u]
minHeap.decreaseKey(v, dist[v])
printArr(dist, V)
# Driver program to test the above functions
graph = Graph(9)
graph.addEdge(0, 1, 4)
graph.addEdge(0, 7, 8)
graph.addEdge(1, 2, 8)
graph.addEdge(1, 7, 11)
graph.addEdge(2, 3, 7)
graph.addEdge(2, 8, 2)
graph.addEdge(2, 5, 4)
graph.addEdge(3, 4, 9)
graph.addEdge(3, 5, 14)
graph.addEdge(4, 5, 10)
graph.addEdge(5, 6, 2)
graph.addEdge(6, 7, 1)
graph.addEdge(6, 8, 6)
graph.addEdge(7, 8, 7)
graph.dijkstra(0)