Accessibility of Digraphs

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);
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 graph

```package 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);
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
*/
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
*/
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);
int s = 0;

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);
}

}
}
}

```

Posted on Thu, 07 Nov 2019 12:03:00 -0500 by Sergey Popov