List<List<Node>> (int k) { try { if (myStart.equals(myFinish)) { return Collections.singletonList(Collections.singletonList(myStart)); } computeDistancesToTarget(); if (!myNextNodes.containsKey(myStart)) { return Collections.emptyList(); } buildOutHeaps(); buildMainHeaps(); PriorityQueue<Sidetracks<Node>> queue = new PriorityQueue<>(); List<FList<HeapNode<Node>>> sidetracks = new ArrayList<>(); sidetracks.add(FList.emptyList()); final Heap<Node> heap = myHeaps.get(myStart); if (heap != null) { queue.add(new Sidetracks<>(0, FList.singleton(heap.getRoot()))); for (int i = 2; i <= k; i++) { if (queue.isEmpty()) break; myProgressIndicator.checkCanceled(); final Sidetracks<Node> current = queue.remove(); sidetracks.add(current.myEdges); final HeapNode<Node> e = current.myEdges.getHead(); final Heap<Node> next = myHeaps.get(e.myEdge.getFinish()); if (next != null) { final HeapNode<Node> f = next.getRoot(); queue.add(new Sidetracks<>(current.myLength + f.myEdge.getDelta(), current.myEdges.prepend(f))); } for (HeapNode<Node> child : e.myChildren) { if (child != null) { queue.add(new Sidetracks<>(current.myLength - e.myEdge.getDelta() + child.myEdge.getDelta(), current.myEdges.getTail().prepend(child))); } } } } return computePathsBySidetracks(sidetracks); } catch (ProcessCanceledException e) { return Collections.emptyList(); } }