Using the depth first algorithm of digraph, it solves the problem of single point connectivity, and can determine whether other vertices are connected with a given starting point.
package com.algorithms.graph; /** * @author yjw * @date 2019/5/20/020 */ public class DirectedDFS { private boolean[] marked; public DirectedDFS(DiGraph g, int s) { marked = new boolean[g.vertexNum()]; dfs(g, s); } /** * Find all vertices reachable from all vertices in sources in a digraph * * @param g * @param sources */ public DirectedDFS(DiGraph g, Iterable<Integer> sources) { marked = new boolean[g.vertexNum()]; for (int s : sources) { if (!marked[s]) { dfs(g, s); } } } private void dfs(DiGraph g, int v) { marked[v] = true; for (int w : g.adj(v)) { if (!marked[w]) { dfs(g,w); } } } /** * Is the return vertex v reachable from a known vertex (s or sources) * @param v * @return */ public boolean marked(int v) { return marked[v]; } public static void main(String[] args) { DiGraph dg = new DiGraph(6); dg.addEdge(0,2,2,0,2,1,2,3,3,2,3,4,3,5); DirectedDFS dfs = new DirectedDFS(dg,3); for (int v = 0; v < dg.vertexNum(); v++) { if (dfs.marked[v]) { System.out.print(v + " "); } } System.out.println(); } }
We verify that the example digraph is reachable from 3 to all vertices.
The way finding of directed graphpackage com.algorithms.graph; import com.algorithms.stack.Stack; /** * @author yjw * @date 2019/5/20/020 */ public class DepthFirstDirectedPaths { private boolean[] marked; private int[] edgeTo; private final int s; public DepthFirstDirectedPaths(DiGraph g, int s) { marked = new boolean[g.vertexNum()]; edgeTo = new int[g.vertexNum()]; this.s = s; dfs(g, s); } private void dfs(DiGraph g, int v) { marked[v] = true; for (int w : g.adj(v)) { if (!marked[w]) { edgeTo[w] = v; dfs(g, w); } } } public boolean hasPathTo(int v) { return marked[v]; } public Iterable<Integer> pathTo(int v) { if (!hasPathTo(v)) return null; Stack<Integer> path = new Stack<>(); for (int x = v; x != s; x = edgeTo[x]) { path.push(x); } path.push(s); return path; } public static void main(String[] args) { DiGraph g = new DiGraph(6); g.addEdge(0,2,2,0,2,1,2,3,3,2,3,4,3,5); int s = 3; DepthFirstDirectedPaths dfs = new DepthFirstDirectedPaths(g, s); for (int v = 0; v < g.vertexNum(); v++) { if (dfs.hasPathTo(v)) { System.out.printf("%d to %d: ", s, v); for (int x : dfs.pathTo(v)) { if (x == s) { System.out.print(x); } else { System.out.print("->" + x); } } System.out.println(); } else { System.out.printf("%d to %d: not connected\n", s, v); } } } }
We can use depth first search to answer the question of whether there is a path from a given starting point to a vertex in a digraph (reachability).
The directed graph in our example is constructed above, and the output is as follows:
3 to 0: 3->2->0 3 to 1: 3->2->1 3 to 2: 3->2 3 to 3: 3 3 to 4: 3->4 3 to 5: 3->5
Similarly, the shortest path of a directed graph can be obtained.
package com.algorithms.graph; import com.algorithms.queue.Queue; import com.algorithms.stack.Stack; /** * @author yjw * @date 2019/5/20/020 */ public class BreadthFirstDirectedPaths { private boolean[] marked; /** * The closest vertex to the current vertex */ private int[] edgeTo; private final int s; public BreadthFirstDirectedPaths(DiGraph g, int s) { marked = new boolean[g.vertexNum()]; edgeTo = new int[g.vertexNum()]; this.s = s; bfs(g, s); } private void bfs(DiGraph g, int s) { Queue<Integer> queue = new Queue<>(); marked[s] = true; queue.enqueue(s); while (!queue.isEmpty()) { int v = queue.dequeue(); /** * Queue all unmarked vertices adjacent to v */ for (int e: g.adj(v)) { if (!marked[e]) { marked[e] = true; edgeTo[e] = v; queue.enqueue(e); } } } } public boolean hasPathTo(int v) { return marked[v]; } public Iterable<Integer> pathTo(int v) { if (!hasPathTo(v)) { return null; } Stack<Integer> path = new Stack<>(); /** * Find the previous vertex step by step from the end of the path */ for (int x = v; x != s ; x = edgeTo[x]) { path.push(x); } /** * Using stack LIFO can print all vertices in the path in sequence */ path.push(s); return path; } public static void main(String[] args) { DiGraph g = new DiGraph(6); g.addEdge(0,2,2,0,2,1,2,3,3,2,3,4,3,5); int s = 0; BreadthFirstDirectedPaths bfs = new BreadthFirstDirectedPaths(g, s); for (int v = 0; v < g.vertexNum(); v++) { if (bfs.hasPathTo(v)) { System.out.printf("%d to %d: ", s, v); for (int x : bfs.pathTo(v)) { if (x == s) { System.out.print(x); } else { System.out.print("->" + x); } } System.out.println(); } else { System.out.printf("%d to %d (-): not connected\n", s, v); } } } }