def prim( paths ):
    data = Data_Manager()
    conn = defaultdict( list )
        
    start = data.get_start()
    #don't  change (12, 16, 17, 21) starting cities
    for x in start:
        visited = []
        path = []
        visited.append(x)
        #append start city key
        connections = data.get_conn(x)
        #(weight, type, connect)
        heapq.heapify(connections)
        while connections:
            #(weight, type, Connection)
            cost, c1, c2 = heapq.heappop(connections)
            if c2 not in visited:
                visited.append(c2)
                path.append((c1, c2, cost))
        
                for x in data.get_conn(c2):
                        heapq.heappush(connections, x)
        paths.append(path)
    #for path in paths:
        #for x in path:
            #print(str.format("({0:3}, {1:3}, {2:5.4}), ", x[0], x[1], x[2]), end = "")
        #print()
    allPaths = []
    for x in paths:
        allPaths.append(_draw_paths(x))
    return allPaths
def dijkstra(start, end):
    data = Data_Manager()
    cities = data.get_cities()
    D = {}
    P = {}
    for city in cities:
        D[city] = float('inf')
        P[city] = ""
        
    D[start] = 0
    remain_cities = cities
    
    while len(remain_cities) > 0:
        short = None
        city = ''
        for x in remain_cities:
            if short == None:
                short = D[x]
                city = x
            elif D[x] < short:
                short = D[x]
                city = x
        remain_cities.remove(city)
        connects = data.get_conn(city)

        for x in connects:
            #|||(weight, type, cost, time)
            if x[1] == city:
                if D[x[2]] == float('inf'):
                    D[x[2]] = D[city] + x[0]
                    P[x[2]] = city
                elif D[x[2]] > D[city] + x[0]:
                    D[x[2]] = D[city] + x[0]
                    P[x[2]] = city
                    
    path = []
    node = end
    while node != start:
        if path.count(node) == 0:
            path.insert(0, node)
            node = P[node]
        else:
            break
        
    path.insert(0, start)
    return (D[end], path)