How do I check if a directed graph is acyclic?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
A directed graph is acyclic when no path follows edge directions and comes back to its starting vertex. That check matters in build systems, dependency resolution, task scheduling, and database migrations, because a cycle means at least one dependency can never be satisfied first.
Detecting Cycles with Depth-First Search
The most direct approach is depth-first search with three states for each node: unvisited, visiting, and visited. A node becomes visiting when recursion enters it and becomes visited after all outgoing edges have been processed. If the traversal reaches another visiting node, the graph has a back edge and therefore a cycle.
This method works well when the graph is stored as an adjacency list and you want an answer in linear time. Its cost is O(V + E), where V is the number of vertices and E is the number of edges.
The output is True for the first graph and False for the second one. The important detail is the distinction between a node already finished and a node currently on the recursion path.
Using Kahn's Algorithm
Kahn's algorithm checks acyclicity through topological sorting. It counts incoming edges for every vertex, repeatedly removes nodes whose indegree is zero, and tracks how many nodes were processed. If every node is removed, the graph is acyclic. If some nodes remain, those leftover nodes are part of a cycle or depend on one.
This approach is also O(V + E) and is often easier to reason about when you already need a topological order.
Kahn's algorithm is iterative, so it avoids recursion depth issues on very deep graphs. It also naturally exposes which nodes can be executed first in a scheduling problem.
Which Method Should You Use?
Use DFS when you only need a yes or no answer and already have a recursive graph traversal in place. Use Kahn's algorithm when you also want a topological ordering or want to stay away from recursion limits.
In practice, both methods are standard and correct. The real decision is about the rest of the code around them. For example, a compiler pipeline might prefer Kahn's algorithm because the sorted result is useful, while a graph validation utility might prefer the more compact DFS solution.
Common Pitfalls
A common bug is using a single visited set and treating any repeated node as a cycle. That is incorrect in directed graphs because revisiting a fully processed node is safe. You need a separate notion of the current recursion path, such as the visiting state.
Another mistake is forgetting nodes that appear only as neighbors. If your graph builder creates keys only for source vertices, indegree counting and traversal can miss sink nodes. Make sure every referenced vertex exists in the internal representation.
With DFS, very deep graphs can hit recursion limits in Python. If that is a concern, either raise the recursion limit carefully or use Kahn's algorithm instead.
Summary
- A directed graph is acyclic when no directed path returns to its starting node.
- DFS detects cycles by finding a back edge to a node currently marked
visiting. - Kahn's algorithm detects cycles when a full topological ordering cannot be produced.
- Both approaches run in linear time relative to vertices and edges.
- Correct graph initialization matters as much as the algorithm itself.

