Open In App

Detect cycle in an undirected graph

Last Updated : 19 Jun, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an undirected graph, The task is to check if there is a cycle in the given graph.

Examples:

Input: N = 4, E = 4

Input-Undirected-Graph

Output: Yes 
Explanation: The diagram clearly shows a cycle 0 to 2 to 1 to 0

Input: N = 4, E = 3

Input-Undirected-Graph-2

Output: No 
Explanation: There is no cycle in the given graph.

Find cycle in Undirected Graph using DFS:

Use DFS from every unvisited node. Depth First Traversal can be used to detect a cycle in a Graph. There is a cycle in a graph only if there is a back edge present in the graph. A back edge is an edge that is indirectly joining a node to itself (self-loop) or one of its ancestors in the tree produced by DFS. 

To find the back edge to any of its ancestors keep a visited array and if there is a back edge to any visited node then there is a loop and return true.

Follow the below steps to implement the above approach:

  • Iterate over all the nodes of the graph and Keep a visited array visited[] to track the visited nodes.
  • Run a Depth First Traversal on the given subgraph connected to the current node and pass the parent of the current node. In each recursive 
    • Set visited[root] as 1.
    • Iterate over all adjacent nodes of the current node in the adjacency list 
      • If it is not visited then run DFS on that node and return true if it returns true.
      • Else if the adjacent node is visited and not the parent of the current node then return true.
    • Return false.

Illustration:

Below is the graph showing how to detect cycle in a graph using DFS:


Below is the implementation of the above approach:

C++
// A C++ Program to detect
// cycle in an undirected graph
#include <iostream>
#include <limits.h>
#include <list>
using namespace std;

// Class for an undirected graph
class Graph {

    // No. of vertices
    int V;

    // Pointer to an array
    // containing adjacency lists
    list<int>* adj;
    bool isCyclicUtil(int v, bool visited[], int parent);

public:
    // Constructor
    Graph(int V);

    // To add an edge to graph
    void addEdge(int v, int w);

    // Returns true if there is a cycle
    bool isCyclic();
};

Graph::Graph(int V)
{
    this->V = V;
    adj = new list<int>[V];
}

void Graph::addEdge(int v, int w)
{

    // Add w to v’s list.
    adj[v].push_back(w);

    // Add v to w’s list.
    adj[w].push_back(v);
}

// A recursive function that
// uses visited[] and parent to detect
// cycle in subgraph reachable
// from vertex v.
bool Graph::isCyclicUtil(int v, bool visited[], int parent)
{

    // Mark the current node as visited
    visited[v] = true;

    // Recur for all the vertices
    // adjacent to this vertex
    list<int>::iterator i;
    for (i = adj[v].begin(); i != adj[v].end(); ++i) {

        // If an adjacent vertex is not visited,
        // then recur for that adjacent
        if (!visited[*i]) {
            if (isCyclicUtil(*i, visited, v))
                return true;
        }

        // If an adjacent vertex is visited and
        // is not parent of current vertex,
        // then there exists a cycle in the graph.
        else if (*i != parent)
            return true;
    }
    return false;
}

// Returns true if the graph contains
// a cycle, else false.
bool Graph::isCyclic()
{

    // Mark all the vertices as not
    // visited and not part of recursion
    // stack
    bool* visited = new bool[V];
    for (int i = 0; i < V; i++)
        visited[i] = false;

    // Call the recursive helper
    // function to detect cycle in different
    // DFS trees
    for (int u = 0; u < V; u++) {

        // Don't recur for u if
        // it is already visited
        if (!visited[u])
            if (isCyclicUtil(u, visited, -1))
                return true;
    }
    return false;
}

// Driver program to test above functions
int main()
{
    Graph g1(5);
    g1.addEdge(1, 0);
    g1.addEdge(0, 2);
    g1.addEdge(2, 1);
    g1.addEdge(0, 3);
    g1.addEdge(3, 4);
    g1.isCyclic() ? cout << "Graph contains cycle\n"
                  : cout << "Graph doesn't contain cycle\n";

    Graph g2(3);
    g2.addEdge(0, 1);
    g2.addEdge(1, 2);
    g2.isCyclic() ? cout << "Graph contains cycle\n"
                  : cout << "Graph doesn't contain cycle\n";

    return 0;
}
Java
// A Java Program to detect cycle in an undirected graph
import java.io.*;
import java.util.*;
@SuppressWarnings("unchecked")
// This class represents a
// directed graph using adjacency list
// representation
class Graph {

    // No. of vertices
    private int V;

    // Adjacency List Representation
    private LinkedList<Integer> adj[];

    // Constructor
    Graph(int v)
    {
        V = v;
        adj = new LinkedList[v];
        for (int i = 0; i < v; ++i)
            adj[i] = new LinkedList();
    }

    // Function to add an edge
    // into the graph
    void addEdge(int v, int w)
    {
        adj[v].add(w);
        adj[w].add(v);
    }

    // A recursive function that
    // uses visited[] and parent to detect
    // cycle in subgraph reachable
    // from vertex v.
    Boolean isCyclicUtil(int v, Boolean visited[],
                         int parent)
    {
        // Mark the current node as visited
        visited[v] = true;
        Integer i;

        // Recur for all the vertices
        // adjacent to this vertex
        Iterator<Integer> it = adj[v].iterator();
        while (it.hasNext()) {
            i = it.next();

            // If an adjacent is not
            // visited, then recur for that
            // adjacent
            if (!visited[i]) {
                if (isCyclicUtil(i, visited, v))
                    return true;
            }

            // If an adjacent is visited
            // and not parent of current
            // vertex, then there is a cycle.
            else if (i != parent)
                return true;
        }
        return false;
    }

    // Returns true if the graph
    // contains a cycle, else false.
    Boolean isCyclic()
    {

        // Mark all the vertices as
        // not visited and not part of
        // recursion stack
        Boolean visited[] = new Boolean[V];
        for (int i = 0; i < V; i++)
            visited[i] = false;

        // Call the recursive helper
        // function to detect cycle in
        // different DFS trees
        for (int u = 0; u < V; u++) {

            // Don't recur for u if already visited
            if (!visited[u])
                if (isCyclicUtil(u, visited, -1))
                    return true;
        }

        return false;
    }

    // Driver method to test above methods
    public static void main(String args[])
    {

        // Create a graph given
        // in the above diagram
        Graph g1 = new Graph(5);
        g1.addEdge(1, 0);
        g1.addEdge(0, 2);
        g1.addEdge(2, 1);
        g1.addEdge(0, 3);
        g1.addEdge(3, 4);
        if (g1.isCyclic())
            System.out.println("Graph contains cycle");
        else
            System.out.println("Graph doesn't contain cycle");

        Graph g2 = new Graph(3);
        g2.addEdge(0, 1);
        g2.addEdge(1, 2);
        if (g2.isCyclic())
            System.out.println("Graph contains cycle");
        else
            System.out.println("Graph doesn't contain cycle");
    }
}
// This code is contributed by Aakash Hasija
Python
# Python Program to detect cycle in an undirected graph
from collections import defaultdict

# This class represents a undirected
# graph using adjacency list representation


class Graph:

    def __init__(self, vertices):

        # No. of vertices
        self.V = vertices  # No. of vertices

        # Default dictionary to store graph
        self.graph = defaultdict(list)

    # Function to add an edge to graph
    def addEdge(self, v, w):

        # Add w to v_s list
        self.graph[v].append(w)

        # Add v to w_s list
        self.graph[w].append(v)

    # A recursive function that uses
    # visited[] and parent to detect
    # cycle in subgraph reachable from vertex v.
    def isCyclicUtil(self, v, visited, parent):

        # Mark the current node as visited
        visited[v] = True

        # Recur for all the vertices
        # adjacent to this vertex
        for i in self.graph[v]:

            # If the node is not
            # visited then recurse on it
            if visited[i] == False:
                if(self.isCyclicUtil(i, visited, v)):
                    return True
            # If an adjacent vertex is
            # visited and not parent
            # of current vertex,
            # then there is a cycle
            elif parent != i:
                return True

        return False

    # Returns true if the graph
    # contains a cycle, else false.

    def isCyclic(self):

        # Mark all the vertices
        # as not visited
        visited = [False]*(self.V)

        # Call the recursive helper
        # function to detect cycle in different
        # DFS trees
        for i in range(self.V):

            # Don't recur for u if it
            # is already visited
            if visited[i] == False:
                if(self.isCyclicUtil
                   (i, visited, -1)) == True:
                    return True

        return False


# Create a graph given in the above diagram
g = Graph(5)
g.addEdge(1, 0)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(0, 3)
g.addEdge(3, 4)

if g.isCyclic():
    print("Graph contains cycle")
else:
    print("Graph doesn't contain cycle ")
g1 = Graph(3)
g1.addEdge(0, 1)
g1.addEdge(1, 2)


if g1.isCyclic():
    print("Graph contains cycle")
else:
    print("Graph doesn't contain cycle ")

# This code is contributed by Neelam Yadav
C#
// C# Program to detect cycle in an undirected graph
using System;
using System.Collections.Generic;

// This class represents a directed graph
// using adjacency list representation
class Graph {
    private int V; // No. of vertices

    // Adjacency List Representation
    private List<int>[] adj;

    // Constructor
    Graph(int v)
    {
        V = v;
        adj = new List<int>[ v ];
        for (int i = 0; i < v; ++i)
            adj[i] = new List<int>();
    }

    // Function to add an edge into the graph
    void addEdge(int v, int w)
    {
        adj[v].Add(w);
        adj[w].Add(v);
    }

    // A recursive function that uses visited[]
    // and parent to detect cycle in subgraph
    // reachable from vertex v.
    Boolean isCyclicUtil(int v, Boolean[] visited,
                         int parent)
    {
        // Mark the current node as visited
        visited[v] = true;

        // Recur for all the vertices
        // adjacent to this vertex
        foreach(int i in adj[v])
        {
            // If an adjacent is not visited,
            // then recur for that adjacent
            if (!visited[i]) {
                if (isCyclicUtil(i, visited, v))
                    return true;
            }

            // If an adjacent is visited and
            // not parent of current vertex,
            // then there is a cycle.
            else if (i != parent)
                return true;
        }
        return false;
    }

    // Returns true if the graph contains
    // a cycle, else false.
    Boolean isCyclic()
    {
        // Mark all the vertices as not visited
        // and not part of recursion stack
        Boolean[] visited = new Boolean[V];
        for (int i = 0; i < V; i++)
            visited[i] = false;

        // Call the recursive helper function
        // to detect cycle in different DFS trees
        for (int u = 0; u < V; u++)

            // Don't recur for u if already visited
            if (!visited[u])
                if (isCyclicUtil(u, visited, -1))
                    return true;

        return false;
    }

    // Driver Code
    public static void Main(String[] args)
    {
        // Create a graph given in the above diagram
        Graph g1 = new Graph(5);
        g1.addEdge(1, 0);
        g1.addEdge(0, 2);
        g1.addEdge(2, 1);
        g1.addEdge(0, 3);
        g1.addEdge(3, 4);
        if (g1.isCyclic())
            Console.WriteLine("Graph contains cycle");
        else
            Console.WriteLine(
                "Graph doesn't contain cycle");

        Graph g2 = new Graph(3);
        g2.addEdge(0, 1);
        g2.addEdge(1, 2);
        if (g2.isCyclic())
            Console.WriteLine("Graph contains cycle");
        else
            Console.WriteLine(
                "Graph doesn't contain cycle");
    }
}

// This code is contributed by PrinciRaj1992
Javascript
// javascript Program to detect cycle in an undirected graph

// This class represents a undirected
// graph using adjacency list representation

class Graph{

    constructor(vertices){
        
        // No. of vertices
        this.V = vertices;
        
        // Default dictionary to store graph
        this.graph = new Array(vertices);
        for(let i = 0; i < vertices; i++){
            this.graph[i] = new Array();
        }
    }
        

    // Function to add an edge to graph
    addEdge(v, w){
        
        // Add w to v_s list
        this.graph[v].push(w);

        // Add v to w_s list
        this.graph[w].push(v);      
    }



    // A recursive function that uses
    // visited[] and parent to detect
    // cycle in subgraph reachable from vertex v.
    isCyclicUtil(v, visited, parent){
 
        // Mark the current node as visited
        visited[v] = true;

        // Recur for all the vertices
        // adjacent to this vertex
        for(let i = 0; i < this.graph[v].length; i++){

            // If the node is not
            // visited then recurse on it
            if(visited[this.graph[v][i]] == false){
                if(this.isCyclicUtil(this.graph[v][i], visited, v) == true){
                    return true;
                }
            }
            // If an adjacent vertex is
            // visited and not parent
            // of current vertex,
            // then there is a cycle
            else if(parent != this.graph[v][i]){
                return true;
            }
        }
        return false;
    }



    // Returns true if the graph
    // contains a cycle, else false.
    isCyclic(){

        // Mark all the vertices
        // as not visited
        let visited = new Array(this.V).fill(false);

        // Call the recursive helper
        // function to detect cycle in different
        // DFS trees
        for(let i = 0; i < this.V; i++){
            // Don't recur for u if it
            // is already visited
            if(visited[i] == false){
                if(this.isCyclicUtil(i, visited, -1) == true){
                    return true;
                }
            }
                
        }

        return false;
    }

}

// Create a graph given in the above diagram
let g = new Graph(5);
g.addEdge(1, 0);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(0, 3);
g.addEdge(3, 4);

if (g.isCyclic() == true){
    console.log("Graph contains cycle");
} 
else{
    console.log("Graph doesn't contain cycle ");
}

let g1 = new Graph(3);
g1.addEdge(0, 1);
g1.addEdge(1, 2);


if(g1.isCyclic() == true){
    console.log("Graph contains cycle");
}   
else{
    console.log("Graph doesn't contain cycle "); 
}
    

// This code is contributed by Gautam goel. 

Output
Graph contains cycle
Graph doesn't contain cycle

Time Complexity: O(V+E), The program does a simple DFS Traversal of the graph which is represented using an adjacency list. So the time complexity is O(V+E).
Auxiliary Space: O(V), To store the visited array O(V) space is required.

Related Articles:



Previous Article
Next Article

Similar Reads

Detect cycle in an undirected graph using BFS
Given an undirected graph, how to check if there is a cycle in the graph? For example, the following graph has a cycle of 1-0-2-1.  Recommended: Please solve it on "PRACTICE" first, before moving on to the solution.We have discussed cycle detection for the directed graph. We have also discussed a union-find algorithm for cycle detection in undirect
5 min read
What is Undirected Graph? | Undirected Graph meaning
An undirected graph is a type of graph where the edges have no specified direction assigned to the them. Characteristics of an Undirected Graph:Edges in an undirected graph are bidirectional in nature.In an undirected graph, there is no concept of a "parent" or "child" vertex as there is no direction to the edges.An undirected graph may contain loo
2 min read
Detect cycle in the graph using degrees of nodes of graph
Given a graph, the task is to detect a cycle in the graph using degrees of the nodes in the graph and print all the nodes that are involved in any of the cycles. If there is no cycle in the graph then print -1. Examples: Input: Output: 0 1 2 Approach: Recursively remove all vertices of degree 1. This can be done efficiently by storing a map of vert
11 min read
Shortest cycle in an undirected unweighted graph
Given an undirected unweighted graph. The task is to find the length of the shortest cycle in the given graph. If no cycle exists print -1. Examples: Input: Output: 4 Cycle 6 -&gt; 1 -&gt; 5 -&gt; 0 -&gt; 6 Input: Output: 3 Cycle 6 -&gt; 1 -&gt; 2 -&gt; 6 Prerequisites: Dijkstra Approach: For every vertex, we check if it is possible to get the shor
8 min read
Minimum labelled node to be removed from undirected Graph such that there is no cycle
Given an undirected graph of N nodes labelled from 1 to N, the task is to find the minimum labelled node that should be removed from the graph such that the resulting graph has no cycle. Note: If the initial graph has no cycle, i.e. no node needs to be removed, print -1. Examples: Input: N = 5, edges[][] = {{5, 1}, {5, 2}, {1, 2}, {2, 3}, {2, 4}} O
15+ min read
Find any simple cycle in an undirected unweighted Graph
Given an un-directed and unweighted connected graph, find a simple cycle in that graph (if it exists). Simple Cycle: A simple cycle is a cycle in a Graph with no repeated vertices (except for the beginning and ending vertex). Basically, if a cycle can't be broken down to two or more cycles, then it is a simple cycle. For better understanding, refer
13 min read
Check if a cycle exists between nodes S and T in an Undirected Graph with only S and T repeating
Given an undirected graph with N nodes and two vertices S &amp; T, the task is to check if a cycle between these two vertices exists or not, such that no other node except S and T appear more than once in that cycle. Print Yes if it exists otherwise print No. Example: Input: N = 7, edges[][] = {{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 2}, {2, 6}
10 min read
Check if a cycle exists between nodes S and T in an Undirected Graph with only S and T repeating | Set - 2
Given an undirected graph with N nodes and two vertices S &amp; T, the task is to check if a cycle between these two vertices exists (and return it) or not, such that no other node except S and T appears more than once in that cycle. Examples: Input: N = 7, edges[][] = {{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 2}, {2, 6}, {6, 0}}, S = 0, T = 4 O
12 min read
Check whether an undirected graph contains cycle or not
Given an undirected graph, the task is to check whether it has a cycle or not, and if it has a cycle return the vertices of the cycle. Examples: Input: Output: Cycle exists. 3 -&gt; 2 -&gt; 1Explanation: Cycle exists for 3 -&gt; 2 -&gt;1 Input: Output: Cycle does not exist. Approach: This problem can be solved using DFS of Graph and Stack to store
15 min read
Find minimum weight cycle in an undirected graph
Given a positive weighted undirected graph, find the minimum weight cycle in it. Examples: Minimum weighted cycle is : Minimum weighed cycle : 7 + 1 + 6 = 14 or 2 + 6 + 2 + 4 = 14 The idea is to use shortest path algorithm. We one by one remove every edge from the graph, then we find the shortest path between two corner vertices of it. We add an ed
15+ min read