def MST_prima(self, start):
     start_found = False
     cur_list = self.adjacency_lists.head
     # Check if start vertex in the graph
     while cur_list != None and start_found == False:
         if cur_list.value == start:
             start_found = True
         cur_list = cur_list.next_list
     if start_found == True:
         tree = UndirectedGraph(
         )  # Create new graph that will be returned as a result
         max_value = self.max()
         distances = [sys.maxsize] * (
             max_value + 1)  # Distances between adjacent vertices in graph
         parent = [-1] * (max_value + 1)  # Parents of each vertex
         minHeap = MinHeap.Minheap(
         )  # Min heap for vertixes that are not processed yet
         minHeap.size = max_value + 1  # Min heap size
         # Add all vertices to the min heap
         for i in range(max_value + 1):
             minHeap.heap.append(minHeap.new_node(i, distances[i]))
             minHeap.pos.append(i)
         minHeap.pos[start] = start
         distances[start] = 0  # Distance from start vertex to itself is 0
         minHeap.decrease_key(
             start, distances[start]
         )  # Change vertex position in heap according to it's new distance
         while minHeap.size > 1:  # Until all vertices are processed
             cur_min = minHeap.extract_min(
             )  # Get minimal vertex with minimal distance from set of processed vertices
             if cur_min.vertex != start:
                 tree.insert(cur_min.vertex, parent[cur_min.vertex],
                             cur_min.distance)
             cur_list = self.adjacency_lists.head
             while cur_list != None and cur_list.value != cur_min.vertex:
                 cur_list = cur_list.next_list
             if cur_list != None:
                 # Loop through adjacent vertices of current minimal vertex and update their distances if it's needed
                 cur = cur_list.next
                 while cur != None:
                     if minHeap.isInMinHeap(cur.value) and distances[
                             cur_min.
                             vertex] != sys.maxsize and cur.edge_value < distances[
                                 cur.value]:
                         distances[
                             cur.value] = cur.edge_value  # Change distance
                         minHeap.decrease_key(cur.value, distances[
                             cur.value])  # Change position in min heap
                         parent[
                             cur.
                             value] = cur_min.vertex  # Add parent of minimal vertex
                     cur = cur.next
         return tree
     else:
         raise Exception("Vertex does not exist")
 def dijkstra(self, start, end):
     cur_list = self.adjacency_lists.head
     start_found = False
     end_found = False
     # Check if start and end vertices are in the graph
     while cur_list != None and (start_found == False
                                 or end_found == False):
         if cur_list.value == start:
             start_found = True
         if cur_list.value == end:
             end_found = True
         cur_list = cur_list.next_list
     if start_found == True and end_found == True:
         max_value = self.max()  # Max value in the graph
         distances = [sys.maxsize] * (max_value + 1
                                      )  # Distances from start to vertex[i]
         minHeap = MinHeap.Minheap(
         )  # Min heap for vertixes that are not processed yet
         minHeap.size = max_value + 1  # Min heap size
         # Add all vertices to the min heap
         for i in range(max_value + 1):
             minHeap.heap.append(minHeap.new_node(i, distances[i]))
             minHeap.pos.append(i)
         minHeap.pos[start] = start
         distances[start] = 0  # Distance from start vertex to itself is 0
         minHeap.decrease_key(
             start, distances[start]
         )  # Change vertex position in heap according to it's new distance
         while minHeap.min_el(
         ) != end:  # While distance from start to end is not found
             cur_min = minHeap.extract_min(
             )  # Get minimal vertex with minimal distance from set of processed vertices
             cur_list = self.adjacency_lists.head
             while cur_list != None and cur_list.value != cur_min.vertex:
                 cur_list = cur_list.next_list
             # Loop through adjacent vertices of current minimal vertex and update their distances if it's needed
             if cur_list != None:
                 cur = cur_list.next
                 while cur != None:
                     if minHeap.isInMinHeap(cur.value) and distances[
                             cur_min.
                             vertex] != sys.maxsize and cur.edge_value + distances[
                                 cur_min.vertex] < distances[cur.value]:
                         distances[cur.value] = cur.edge_value + distances[
                             cur_min.vertex]  # Change distance
                         minHeap.decrease_key(cur.value, distances[
                             cur.value])  # Change position in min heap
                     cur = cur.next
         return distances[end]
     else:
         raise Exception("Path does not exist")