

import math
import sys


class 					A		:







    """simple docstring"""





    def __init__( self					:			Optional[Any]						)->       Tuple:





        '''simple docstring'''







        A__        =  0
        A__        =  []
        A__        =  {}  # To store the pos of node in array


    def 		snake_case__	( self					:			Any						)->       Any:





        '''simple docstring'''







        return self.cur_size == 0


    def 		snake_case__	( self					:			Any,lowercase_					:			List[str]						)->       Tuple:





        '''simple docstring'''







        A__        =  self.left(__SCREAMING_SNAKE_CASE						)
        A__        =  self.right(__SCREAMING_SNAKE_CASE						)
        if lc < self.cur_size and self.array(__SCREAMING_SNAKE_CASE						)[0] < self.array(__SCREAMING_SNAKE_CASE						)[0]:
            A__        =  lc
        else:
            A__        =  idx
        if rc < self.cur_size and self.array(__SCREAMING_SNAKE_CASE						)[0] < self.array(__SCREAMING_SNAKE_CASE						)[0]:
            A__        =  rc
        if smallest != idx:
            self.swap(__SCREAMING_SNAKE_CASE,__SCREAMING_SNAKE_CASE						)
            self.min_heapify(__SCREAMING_SNAKE_CASE						)


    def 		snake_case__	( self					:			Tuple,lowercase_					:			Optional[Any]						)->       Optional[int]:





        '''simple docstring'''







        A__        =  self.cur_size
        self.cur_size += 1
        self.array.append((sys.maxsize, tup[1])						)
        self.decrease_key((sys.maxsize, tup[1]),tup[0]						)


    def 		snake_case__	( self					:			Optional[Any]						)->       List[Any]:





        '''simple docstring'''







        A__        =  self.array[0][1]
        A__        =  self.array[self.cur_size - 1]
        self.cur_size -= 1
        self.min_heapify(1						)
        del self.pos[min_node]
        return min_node


    def 		snake_case__	( self					:			str,lowercase_					:			Optional[int]						)->       Optional[Any]:





        '''simple docstring'''







        return 2 * i + 1


    def 		snake_case__	( self					:			Dict,lowercase_					:			List[str]						)->       Any:





        '''simple docstring'''







        return 2 * i + 2


    def 		snake_case__	( self					:			Tuple,lowercase_					:			Optional[Any]						)->       Dict:





        '''simple docstring'''







        return math.floor(i / 2						)


    def 		snake_case__	( self					:			Dict,lowercase_					:			Optional[Any],lowercase_					:			Optional[Any]						)->       Tuple:





        '''simple docstring'''







        A__        =  j
        A__        =  i
        A__        =  self.array[i]
        A__        =  self.array[j]
        A__        =  temp


    def 		snake_case__	( self					:			str,lowercase_					:			Any,lowercase_					:			str						)->       List[str]:





        '''simple docstring'''







        A__        =  self.pos[tup[1]]
        # assuming the new_d is atmost old_d
        A__        =  (new_d, tup[1])
        while idx > 0 and self.array[self.par(__SCREAMING_SNAKE_CASE						)][0] > self.array[idx][0]:
            self.swap(__SCREAMING_SNAKE_CASE,self.par(__SCREAMING_SNAKE_CASE						)						)
            A__        =  self.par(__SCREAMING_SNAKE_CASE						)




class 					A		:







    """simple docstring"""





    def __init__( self					:			Union[str, Any],lowercase_					:			Dict						)->       Optional[Any]:





        '''simple docstring'''







        A__        =  {}  # To store graph: u -> (v,w)
        A__        =  num  # Number of nodes in graph
        # To store the distance from source vertex
        A__        =  [0] * self.num_nodes
        A__        =  [-1] * self.num_nodes  # To store the path


    def 		snake_case__	( self					:			str,lowercase_					:			Optional[Any],lowercase_					:			Union[str, Any],lowercase_					:			Dict						)->       List[Any]:





        '''simple docstring'''







        if u in self.adjList:
            self.adjList[u].append((v, w)						)
        else:
            A__        =  [(v, w)]

        # Assuming undirected graph
        if v in self.adjList:
            self.adjList[v].append((u, w)						)
        else:
            A__        =  [(u, w)]


    def 		snake_case__	( self					:			List[Any]						)->       Tuple:





        '''simple docstring'''







        for u in self.adjList:
            print(__SCREAMING_SNAKE_CASE,'->',' -> '.join(str(F'{v}({w})'						) for v, w in self.adjList[u]						)						)


    def 		snake_case__	( self					:			Tuple,lowercase_					:			Optional[int]						)->       List[Any]:





        '''simple docstring'''







        A__        =  [-1] * self.num_nodes
        # src is the source node
        A__        =  0
        A__        =  PriorityQueue()
        q.insert((0, src)						)  # (dist from src, node)
        for u in self.adjList:
            if u != src:
                A__        =  sys.maxsize  # Infinity
                A__        =  -1

        while not q.is_empty():
            A__        =  q.extract_min()  # Returns node with the min dist from source
            # Update the distance of all the neighbours of u and
            # if their prev dist was INFINITY then push them in Q
            for v, w in self.adjList[u]:
                A__        =  self.dist[u] + w
                if self.dist[v] > new_dist:
                    if self.dist[v] == sys.maxsize:
                        q.insert((new_dist, v)						)
                    else:
                        q.decrease_key((self.dist[v], v),__SCREAMING_SNAKE_CASE						)
                    A__        =  new_dist
                    A__        =  u

        # Show the shortest distances from src
        self.show_distances(__SCREAMING_SNAKE_CASE						)


    def 		snake_case__	( self					:			str,lowercase_					:			Union[str, Any]						)->       int:





        '''simple docstring'''







        print(F'Distance from node: {src}'						)
        for u in range(self.num_nodes						):
            print(F'Node {u} has distance: {self.dist[u]}'						)


    def 		snake_case__	( self					:			List[str],lowercase_					:			Dict,lowercase_					:			Optional[int]						)->       List[str]:





        '''simple docstring'''







        A__        =  []
        A__        =  0
        A__        =  dest
        # Backtracking from dest to src
        while self.par[temp] != -1:
            path.append(__SCREAMING_SNAKE_CASE						)
            if temp != src:
                for v, w in self.adjList[temp]:
                    if v == self.par[temp]:
                        cost += w
                        break
            A__        =  self.par[temp]
        path.append(__SCREAMING_SNAKE_CASE						)
        path.reverse()

        print(F'----Path to reach {dest} from {src}----'						)
        for u in path:
            print(F'{u}',end=' '						)
            if u != dest:
                print('-> ',end=''						)

        print('\nTotal cost of path: ',__SCREAMING_SNAKE_CASE						)


if __name__ == "__main__":
     lowercase_									=    Graph(9)
     graph.add_edge(0, 1, 4)
     graph.add_edge(0, 7, 8)
     graph.add_edge(1, 2, 8)
     graph.add_edge(1, 7, 11)
     graph.add_edge(2, 3, 7)
     graph.add_edge(2, 8, 2)
     graph.add_edge(2, 5, 4)
     graph.add_edge(3, 4, 9)
     graph.add_edge(3, 5, 14)
     graph.add_edge(4, 5, 10)
     graph.add_edge(5, 6, 2)
     graph.add_edge(6, 7, 1)
     graph.add_edge(6, 8, 6)
     graph.add_edge(7, 8, 7)
     graph.show_graph()
     graph.dijkstra(0)
     graph.show_path(0, 4)

# OUTPUT
# 0 -> 1(4) -> 7(8)
# 1 -> 0(4) -> 2(8) -> 7(11)
# 7 -> 0(8) -> 1(11) -> 6(1) -> 8(7)
# 2 -> 1(8) -> 3(7) -> 8(2) -> 5(4)
# 3 -> 2(7) -> 4(9) -> 5(14)
# 8 -> 2(2) -> 6(6) -> 7(7)
# 5 -> 2(4) -> 3(14) -> 4(10) -> 6(2)
# 4 -> 3(9) -> 5(10)
# 6 -> 5(2) -> 7(1) -> 8(6)
# Distance from node: 0
# Node 0 has distance: 0
# Node 1 has distance: 4
# Node 2 has distance: 12
# Node 3 has distance: 19
# Node 4 has distance: 21
# Node 5 has distance: 11
# Node 6 has distance: 9
# Node 7 has distance: 8
# Node 8 has distance: 14
# ----Path to reach 4 from 0----
# 0 -> 7 -> 6 -> 5 -> 4
# Total cost of path:  21






def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round((float(_UpperCAmelCase							) * 9 / 5) + 32  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round(float(_UpperCAmelCase							) + 2_73.15  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round((float(_UpperCAmelCase							) * 9 / 5) + 4_91.67  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round((float(_UpperCAmelCase							) - 32) * 5 / 9  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round(((float(_UpperCAmelCase							) - 32) * 5 / 9) + 2_73.15  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round(float(_UpperCAmelCase							) + 4_59.67  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round(float(_UpperCAmelCase							) - 2_73.15  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round(((float(_UpperCAmelCase							) - 2_73.15) * 9 / 5) + 32  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round((float(_UpperCAmelCase							) * 9 / 5)  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round((float(_UpperCAmelCase							) - 4_91.67) * 5 / 9  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round(float(_UpperCAmelCase							) - 4_59.67  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round((float(_UpperCAmelCase							) * 5 / 9)  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round((float(_UpperCAmelCase							) * 1.25 + 2_73.15)  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round((float(_UpperCAmelCase							) * 2.25 + 32)  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round((float(_UpperCAmelCase							) * 1.25)  ,					_UpperCAmelCase							)





def 	__snake_case      (     _UpperCAmelCase  ,					_UpperCAmelCase = 2							):
    return round((float(_UpperCAmelCase							) * 2.25 + 32 + 4_59.67)  ,					_UpperCAmelCase							)


if __name__ == "__main__":
 import doctest

 doctest.testmod()





