input: Write a python function to implement Dijkstra's algorithm to find the shortest path in a graph.
  assert dijkstra([[0, 1, 4, 0, 0, 0], [1, 0, 4, 2, 7, 0], [4, 4, 0, 3, 5, 0], [0, 2, 3, 0, 4, 6], [0, 7, 5, 4, 0, 7], [0, 0, 0, 6, 7, 0]], 0)==[None, 0, 0, 1, 1, 3]
  assert dijkstra([[0, 2, 0, 1, 0], [2, 0, 3, 2, 0], [0, 3, 0, 0, 1], [1, 2, 0, 0, 3], [0, 0, 1, 3, 0]], 0)==[None, 0, 1, 0, 2]
  assert dijkstra([[0, 0, 1, 0], [0, 0, 0, 2], [1, 0, 0, 3], [0, 2, 3, 0]], 2)==[2, 3, None, 2]
output: def dijkstra(graph, start):
      n = len(graph)
      visited = [False] * n
      distance = [float('inf')] * n
      distance[start] = 0
      predecessor = [None] * n
      
      for _ in range(n):
          min_distance = float('inf')
          u = None
          for i in range(n):
              if not visited[i] and distance[i] < min_distance:
                  min_distance = distance[i]
                  u = i
                  
          if u is None:
              break
          
          visited[u] = True
          
          for v in range(n):
              if graph[u][v] > 0 and not visited[v]:
                  new_distance = distance[u] + graph[u][v]
                  if new_distance < distance[v]:
                      distance[v] = new_distance
                      predecessor[v] = u
      
      return predecessor