Cycle Detection in Directed Graph (DFS)

Cycle Detection in Directed Graph using DFS

Cycle detection in a directed graph is an important problem in computer science, particularly in dependency resolution, scheduling, and detecting deadlocks. This blog explains how to detect a cycle in a directed graph using Depth First Search (DFS) with the help of two auxiliary vectors: visited and pathVis. We'll also provide a clear implementation in C++.


Approach

  1. Graph Representation: A directed graph is represented as an adjacency list.

  2. Visited Vectors:

    • visited: Keeps track of whether a node has been visited in any DFS traversal.

    • pathVis: Keeps track of whether a node is part of the current DFS recursion stack.

  3. Cycle Detection Logic:

    • If a node is visited and is part of the current recursion stack (pathVis[node] is true), a cycle is detected.

    • After exploring all paths from a node, it is removed from the recursion stack by setting pathVis[node] to false.

  4. DFS Function:

    • Traverse all neighbors of the current node.

    • If a neighbor is not visited, recursively call DFS for that neighbor.

    • If a neighbor is visited and part of the current recursion stack, a cycle is present.

  5. Iterate for All Nodes:

    • Since the graph may be disconnected, start DFS from each unvisited node.


Pseudo Code

Here is a pseudo code to make the approach easier for beginners:


Implementation in C++

Below is the C++ code to detect a cycle in a directed graph using DFS:


Explanation of Code

  1. Graph Initialization:

    • The constructor initializes the graph with a given number of vertices (V).

    • The adjacency list (adj) is resized to accommodate V vertices.

  2. Adding Edges:

    • addEdge adds a directed edge from vertex u to vertex v.

  3. DFS Function:

    • Marks the current node as visited and adds it to the recursion stack (pathVis).

    • Traverses all neighbors of the current node. If a neighbor is unvisited, DFS is called recursively. If a visited neighbor is found in the recursion stack, a cycle is detected.

    • Removes the node from the recursion stack before returning.

  4. Cycle Detection:

    • hasCycle iterates through all nodes. For each unvisited node, it initiates a DFS to check for cycles.

  5. Output:

    • Prints whether the graph contains a cycle.


Time and Space Complexity

  • Time Complexity:

    • Each vertex and edge is visited once, so the complexity is O(V + E), where V is the number of vertices and E is the number of edges.

  • Space Complexity:

    • The space required for the adjacency list is O(V + E).

    • Additional space for the visited and pathVis vectors is O(V).

    • The recursion stack may use space up to O(V) in the worst case.

    • Overall, the space complexity is O(V + E).


Applications

  • Detecting deadlocks in operating systems.

  • Verifying dependencies in build systems or package managers.

  • Identifying loops in workflows or processes.


Last updated