# shortest path in a directed graph by dijkstraâ €™ s algorithm | python3 implementation to find the shortest path in a directed graph from source vertex to the destination vertex ; class of the node ; adjacency list that shows the vertexnumber of child vertex and the weight of the edge ; function to add the child for the given node ; function to find the distance of the node from the given source vertex to the destination vertex ; stores distance of each vertex from source vertex ; bool array that shows whether the vertex ' i ' is visited or not ; set of vertices that has a parent ( one or more ) marked as visited ; mark current as visited ; inserting into the visited vertex ; condition to check the distance is correct and update it if it is minimum from the previous computed distance ; the new current ; loop to update the distance of the vertices of the graph ; function to print the path from the source vertex to the destination vertex ; condition to check if there is no path between the vertices ; 

class Pair:
    def __init__(self, first, second):
        self .first = first
        self .second = second


infi = 1000000000


class Node:
    def __init__(self, vertexNumber):
        self .vertexNumber = vertexNumber
        self .children = []

    def Add_child(self, vNumber, length):
        p = Pair(vNumber, length)
        self .children .append(p)


def printPath(path, i, s):
    if (i != s):
        if (path[i] == -1):
            print("Path not found!!")
            return
        printPath(path, path[i], s)
        print(path[i] + " ")

def dijkstraDist(g, s, path):
    dist = [infi for i in range(len(g))]
    visited = [False for i in range(len(g))]
    for i in range(len(g)):
        path[i] = -1
    dist[s] = 0
    path[s] = -1
    current = s
    sett = set()
    while (True):
        visited[current] = True
        for i in range(len(g[current].children)):
            v = g[current].children[i].first
            if (visited[v]):
                continue
            sett .add(v)
            alt = dist[current] + g[current].children[i].second
            if (alt < dist[v]):
                dist[v] = alt
                path[v] = current
        if current in sett:
            sett .remove(current)
        if (len(sett) == 0):
            break
        minDist = infi
        index = 0
        for a in sett:
            if (dist[a] < minDist):
                minDist = dist[a]
                index = a
        current = index
    return dist


if __name__ == '__main__':
    v = []
    n = 4
    s = 0
    for i in range(n):
        a = Node(i)
        v .append(a)
    v[0].Add_child(1, 1)
    v[0].Add_child(2, 4)
    v[1].Add_child(2, 2)
    v[1].Add_child(3, 6)
    v[2].Add_child(3, 3)
    path = [0 for i in range(len(v))]
    dist = dijkstraDist(v, s, path)
    for i in range(len(dist)):
        if (dist[i] == infi):
            print("{0} and {1} are not " + "connected".format(i, s))
            continue
        print(
            "Distance of {}th vertex from source vertex {} is: {}".format(
                i,
                s,
                dist[i]))

# Expected output:
Distance of 0th vertex from source vertex 0 is: 0
Distance of 1th vertex from source vertex 0 is: 1
Distance of 2th vertex from source vertex 0 is: 3
Distance of 3th vertex from source vertex 0 is: 6