Given a directed graph, check if it is a DAG (Directed Acyclic Graph) or not. A DAG is a digraph (directed graph) that contains no cycles.

The following graph contains a cycle 0—1—3—0, so it’s not DAG. If we remove edge 3–0 from it, it will become a DAG.

 
Back edge in a directed graph

Practice this problem

 
Recommended Read:

Types of edges involved in DFS and relation between them

Arrival and departure time of vertices in DFS

 
We can use Depth–first search (DFS) to solve this problem. The idea is to find if any back-edge is present in the graph or not. A digraph is a DAG if there is no back-edge present in the graph. Recall that a back-edge is an edge from a vertex to one of its ancestors in the DFS tree.

 
Fact: For an edge u —> v in a directed graph, an edge is a back edge if departure[u] < departure[v].

Proof: We have already discussed the relationship between all four types of edges involved in the DFS in the previous post. Following are the relationships we have seen between the departure time for different types of edges involved in a DFS of a directed graph:

Tree edge (u, v): departure[u] > departure[v]
Back edge (u, v): departure[u] < departure[v]
Forward edge (u, v): departure[u] > departure[v]
Cross edge (u, v): departure[u] > departure[v]

Note that for tree edge, forward edge and cross edge, departure[u] > departure[v]. But only for the back edge, the relationship departure[u] < departure[v] holds true. So, it is guaranteed that an edge (u, v) is a back-edge, not some other edge if departure[u] < departure[v].

 
Types of edges involved in DFS and relation between them

The algorithm can be implemented as follows in C++, Java, and Python:

C++


Download  Run Code

Output:

The graph is not a DAG

Java


Download  Run Code

Output:

The graph is not a DAG

Python


Download  Run Code

Output:

The graph is not a DAG

The time complexity of the above solutions is O(V + E), where V and E are the total number of vertices and edges in the graph, respectively.