/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
/**
*
* 2 - 4
* / \ \
* / 5---- 7
* 1 /
* \ 8 /
* \ / \ /
* 3 -- 6
*
*/
class FindAllShortestPathsInUnweightedGraph {
public static List
<List
<String
>> findAllShortestPaths
(Graph graph,
String from,
String to
) { LinkedHashMap<Node, Object> queue = new LinkedHashMap<>();
Set<Node> visited = new HashSet<>();
queue.put(new Node(from), mock);
Node nodeTo = null;
while (queue.keySet().size() > 0) {
Node next = queue.keySet().iterator().next();
if (next.key.equals(to)) {
// base case: we found the end node and processed all edges to it -> we are done
nodeTo = next;
break;
}
for (Node n: graph.adjacents(next.key)) {
if (!visited.contains(n)) {
if (queue.get(n) == null) {
queue.put(n, mock);
}
n.addParent(next);
}
}
// removing the node from queue
queue.remove(next);
visited.add(next);
}
if (nodeTo == null) {
}
// Now performing the dfs from target node to gather all paths
List<List<String>> result = new ArrayList<>();
dfs(nodeTo, result, new LinkedList<>());
return result;
}
private static void dfs(Node n, List<List<String>> result, LinkedList<String> path) {
path.addFirst(n.key);
if (n.getParents().size() == 0) {
// base case: we came to target vertex
result.add(new ArrayList<>(path));
}
for (Node p: n.getParents()) {
dfs(p, result, path);
}
// do not forget to remove the processed element from path
path.removeFirst();
}
private static class Graph {
Map
<String, Set
<Node
>> adjacencyList
= new HashMap
<>();
addEdge(to, from);
addEdge(from, to);
}
Set<Node> list = adjacencyList.get(from);
if (list == null) {
list = new LinkedHashSet<>();
adjacencyList.put(from, list);
}
list.add(Node.get(to));
}
public Set
<Node
> adjacents
(String v
) { return adjacencyList.get(v);
}
}
private static class Node {
Set<Node> parents = new LinkedHashSet<>();
private static Map
<String, Node
> map
= new HashMap
<>();
public static Node get
(String str
) { // inner interning of nodes
Node res = map.get(str);
if (res == null) {
res = new Node(str);
map.put(str, res);
}
return res;
}
key = str;
}
public void addParent(Node n) {
parents.add(n);
}
public Set<Node> getParents() {
return parents;
}
public boolean equals
(Object n
) { return key.equals(((Node)n).key);
}
public int hashCode() {
return key.hashCode();
}
@Override
return key;
}
}
public static void main
(String[] args
) { Graph graph = new Graph();
graph.add("1", "2");
graph.add("1", "3");
graph.add("2", "4");
graph.add("2", "5");
graph.add("4", "7");
graph.add("5", "7");
graph.add("3", "8");
graph.add("3", "6");
graph.add("8", "6");
graph.add("6", "7");
graph.add("7", "5");
System.
out.
println(findAllShortestPaths
(graph,
"1",
"7")); }
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CgovKiBOYW1lIG9mIHRoZSBjbGFzcyBoYXMgdG8gYmUgIk1haW4iIG9ubHkgaWYgdGhlIGNsYXNzIGlzIHB1YmxpYy4gKi8KLyoqCiAqICAgICAKICogICAgIDIgLSA0CiAqICAgIC8gXCAgICBcCiAqICAgLyAgIDUtLS0tIDcKICogMSAgICAgICAgICAvCiAqICBcICAgOCAgICAvCiAqICAgXCAvICBcIC8KICogICAgMyAtLSA2CiAqIAogKi8KY2xhc3MgRmluZEFsbFNob3J0ZXN0UGF0aHNJblVud2VpZ2h0ZWRHcmFwaCB7CiAgICBwcml2YXRlIHN0YXRpYyBPYmplY3QgbW9jayA9IG5ldyBPYmplY3QoKTsKICAgIHB1YmxpYyBzdGF0aWMgTGlzdDxMaXN0PFN0cmluZz4+IGZpbmRBbGxTaG9ydGVzdFBhdGhzKEdyYXBoIGdyYXBoLCBTdHJpbmcgZnJvbSwgU3RyaW5nIHRvKSB7CiAgICAgICAgTGlua2VkSGFzaE1hcDxOb2RlLCBPYmplY3Q+IHF1ZXVlID0gbmV3IExpbmtlZEhhc2hNYXA8PigpOwogICAgICAgIFNldDxOb2RlPiB2aXNpdGVkID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIHF1ZXVlLnB1dChuZXcgTm9kZShmcm9tKSwgbW9jayk7CgogICAgICAgIE5vZGUgbm9kZVRvID0gbnVsbDsKICAgICAgICB3aGlsZSAocXVldWUua2V5U2V0KCkuc2l6ZSgpID4gMCkgewogICAgICAgICAgICBOb2RlIG5leHQgPSBxdWV1ZS5rZXlTZXQoKS5pdGVyYXRvcigpLm5leHQoKTsKCiAgICAgICAgICAgIGlmIChuZXh0LmtleS5lcXVhbHModG8pKSB7CiAgICAgICAgICAgICAgICAvLyBiYXNlIGNhc2U6IHdlIGZvdW5kIHRoZSBlbmQgbm9kZSBhbmQgcHJvY2Vzc2VkIGFsbCBlZGdlcyB0byBpdCAtPiB3ZSBhcmUgZG9uZQogICAgICAgICAgICAgICAgbm9kZVRvID0gbmV4dDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKE5vZGUgbjogZ3JhcGguYWRqYWNlbnRzKG5leHQua2V5KSkgewogICAgICAgICAgICAgICAgaWYgKCF2aXNpdGVkLmNvbnRhaW5zKG4pKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHF1ZXVlLmdldChuKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXVlLnB1dChuLCBtb2NrKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbi5hZGRQYXJlbnQobmV4dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHJlbW92aW5nIHRoZSBub2RlIGZyb20gcXVldWUKICAgICAgICAgICAgcXVldWUucmVtb3ZlKG5leHQpOwogICAgICAgICAgICB2aXNpdGVkLmFkZChuZXh0KTsKICAgICAgICB9CiAgICAgICAgaWYgKG5vZGVUbyA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKICAgICAgICB9CgogICAgICAgIC8vIE5vdyBwZXJmb3JtaW5nIHRoZSBkZnMgZnJvbSB0YXJnZXQgbm9kZSB0byBnYXRoZXIgYWxsIHBhdGhzCiAgICAgICAgTGlzdDxMaXN0PFN0cmluZz4+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIGRmcyhub2RlVG8sIHJlc3VsdCwgbmV3IExpbmtlZExpc3Q8PigpKTsKCiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGRmcyhOb2RlIG4sIExpc3Q8TGlzdDxTdHJpbmc+PiByZXN1bHQsIExpbmtlZExpc3Q8U3RyaW5nPiBwYXRoKSB7CiAgICAgICAgcGF0aC5hZGRGaXJzdChuLmtleSk7CiAgICAgICAgaWYgKG4uZ2V0UGFyZW50cygpLnNpemUoKSA9PSAwKSB7CiAgICAgICAgICAgIC8vIGJhc2UgY2FzZTogd2UgY2FtZSB0byB0YXJnZXQgdmVydGV4CiAgICAgICAgICAgIHJlc3VsdC5hZGQobmV3IEFycmF5TGlzdDw+KHBhdGgpKTsKICAgICAgICB9CiAgICAgICAgZm9yIChOb2RlIHA6IG4uZ2V0UGFyZW50cygpKSB7CiAgICAgICAgICAgIGRmcyhwLCByZXN1bHQsIHBhdGgpOwogICAgICAgIH0KICAgICAgICAvLyBkbyBub3QgZm9yZ2V0IHRvIHJlbW92ZSB0aGUgcHJvY2Vzc2VkIGVsZW1lbnQgZnJvbSBwYXRoCiAgICAgICAgcGF0aC5yZW1vdmVGaXJzdCgpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEdyYXBoIHsKICAgICAgICBNYXA8U3RyaW5nLCBTZXQ8Tm9kZT4+IGFkamFjZW5jeUxpc3QgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgICAgIHB1YmxpYyB2b2lkIGFkZChTdHJpbmcgZnJvbSwgU3RyaW5nIHRvKSB7CiAgICAgICAgICAgIGFkZEVkZ2UodG8sIGZyb20pOwogICAgICAgICAgICBhZGRFZGdlKGZyb20sIHRvKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBhZGRFZGdlKFN0cmluZyBmcm9tLCBTdHJpbmcgdG8pIHsKICAgICAgICAgICAgU2V0PE5vZGU+IGxpc3QgPSBhZGphY2VuY3lMaXN0LmdldChmcm9tKTsKCiAgICAgICAgICAgIGlmIChsaXN0ID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGxpc3QgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgICAgICAgICBhZGphY2VuY3lMaXN0LnB1dChmcm9tLCBsaXN0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsaXN0LmFkZChOb2RlLmdldCh0bykpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFNldDxOb2RlPiBhZGphY2VudHMoU3RyaW5nIHYpIHsKICAgICAgICAgICAgcmV0dXJuIGFkamFjZW5jeUxpc3QuZ2V0KHYpOwogICAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTm9kZSB7CiAgICAgICAgU2V0PE5vZGU+IHBhcmVudHMgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgTWFwPFN0cmluZywgTm9kZT4gbWFwID0gbmV3IEhhc2hNYXA8PigpOwogICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGtleTsKCiAgICAgICAgcHVibGljIHN0YXRpYyBOb2RlIGdldChTdHJpbmcgc3RyKSB7CiAgICAgICAgICAgIC8vIGlubmVyIGludGVybmluZyBvZiBub2RlcwogICAgICAgICAgICBOb2RlIHJlcyA9IG1hcC5nZXQoc3RyKTsKICAgICAgICAgICAgaWYgKHJlcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXMgPSBuZXcgTm9kZShzdHIpOwogICAgICAgICAgICAgICAgbWFwLnB1dChzdHIsIHJlcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBOb2RlKFN0cmluZyBzdHIpIHsKICAgICAgICAgICAga2V5ID0gc3RyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgYWRkUGFyZW50KE5vZGUgbikgewogICAgICAgICAgICBwYXJlbnRzLmFkZChuKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIFNldDxOb2RlPiBnZXRQYXJlbnRzKCkgewogICAgICAgICAgICByZXR1cm4gcGFyZW50czsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbikgewogICAgICAgICAgICByZXR1cm4ga2V5LmVxdWFscygoKE5vZGUpbikua2V5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgcmV0dXJuIGtleS5oYXNoQ29kZSgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIGtleTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewogICAgICAgIEdyYXBoIGdyYXBoID0gbmV3IEdyYXBoKCk7CgogICAgICAgIGdyYXBoLmFkZCgiMSIsICIyIik7CiAgICAgICAgZ3JhcGguYWRkKCIxIiwgIjMiKTsKICAgICAgICBncmFwaC5hZGQoIjIiLCAiNCIpOwogICAgICAgIGdyYXBoLmFkZCgiMiIsICI1Iik7CiAgICAgICAgZ3JhcGguYWRkKCI0IiwgIjciKTsKICAgICAgICBncmFwaC5hZGQoIjUiLCAiNyIpOwogICAgICAgIGdyYXBoLmFkZCgiMyIsICI4Iik7CiAgICAgICAgZ3JhcGguYWRkKCIzIiwgIjYiKTsKICAgICAgICBncmFwaC5hZGQoIjgiLCAiNiIpOwogICAgICAgIGdyYXBoLmFkZCgiNiIsICI3Iik7CiAgICAgICAgZ3JhcGguYWRkKCI3IiwgIjUiKTsKCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGZpbmRBbGxTaG9ydGVzdFBhdGhzKGdyYXBoLCAiMSIsICI3IikpOwogICAgfQp9Cg==
[[1, 2, 4, 7], [1, 2, 5, 7], [1, 3, 6, 7], [1, 3, 8, 6, 7]]