public void shortestPathOptimized(Integer source) {
        PriorityQueue<Pair> queue = new PriorityQueue<>();
        Map<Integer, Pair> map = new HashMap<>();
        for (Integer vertex : graph.getVertices()) {
            Pair pair;
            if (source.equals(vertex)) pair = new Pair(vertex, 0d);
            else pair = new Pair(vertex, Double.POSITIVE_INFINITY);
            queue.add(pair);
            map.put(vertex, pair);
        }
        while (!queue.isEmpty()) {

            Pair pair = queue.remove();

            if (map.get(pair.label) != pair) continue; // if pair is already updated

            for (Edge edge : graph.getEdges(pair.label)) {
                Double newPath = pair.weight + edge.getWeight();
                if (newPath < map.get(edge.getTo()).weight) {
                    Pair newPair = new Pair(edge.getTo(), newPath);
                    map.put(edge.getTo(), newPair);
                    queue.add(newPair);
                }
            }
        }


    }
This is optimized version of shortest path algorithm, whose running time is O(E logE)
this works better than other implementations in practise
src/algo/graph/Dijsktra.java