Detect cycle in an undirected graph - GeeksforGeeks

18 Jan, 2022
Given an undirected graph, how to check if there is a cycle in the graph? Example, 
Input: n = 4, e = 4 Output: Yes Explanation: 0 1, 1 2, 2 3, 0 2 Diagram:  
The diagram clearly shows a cycle 0 to 2 to 1 to 0Input:n = 4, e = 3 0 1, 1 2, 2 3 Output:No Explanation: Diagram: 
The diagram clearly shows no cycle 
Articles about cycle detection: 
cycle detection for directed graph.
union-find algorithm for cycle detection in undirected graphs.
Approach: Run a DFS from every unvisited node. Depth First Traversal can be used to detect a cycle in a Graph. DFS for a connected graph produces a tree. 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 joining a node to itself (self-loop) or one of its ancestor 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.Algorithm: 
Create the graph using the given number of edges and vertices.Create a recursive function that have current index or vertex, visited array and parent node.Mark the current node as visited .Find all the vertices which are not visited and are adjacent to the current node. Recursively call the function for those vertices, If the recursive function returns true return true.If the adjacent node is not parent and already visited then return true.Create a wrapper class, that calls the recursive function for all the vertices and if any function returns true, return true.Else if for all vertices the function returns false return false.
Create the graph using the given number of edges and vertices.
Create a recursive function that have current index or vertex, visited array and parent node.
Mark the current node as visited .
Find all the vertices which are not visited and are adjacent to the current node. Recursively call the function for those vertices, If the recursive function returns true return true.
If the adjacent node is not parent and already visited then return true.
Create a wrapper class, that calls the recursive function for all the vertices and if any function returns true, return true.
Else if for all vertices the function returns false return false.
Dry Run: 
Implementation: 
C++
Java
Python3
C#
// A C++ Program to detect// cycle in an undirected graph#include<iostream>#include <list>#include <limits.h>using namespace std; // Class for an undirected graphclass 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 functionsint 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;}
// A Java Program to detect cycle in an undirected graphimport java.io.*;import java.util.*;// This class represents a// directed graph using adjacency list// representationclass 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 contains 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 contains cycle");    }}// This code is contributed by Aakash Hasija
# Python Program to detect cycle in an undirected graphfrom collections import defaultdict  # This class represents a undirected# graph using adjacency list representationclass 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 diagramg = 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 does not contain cycle ")g1 = Graph(3)g1.addEdge(0,1)g1.addEdge(1,2)  if g1.isCyclic():    print ("Graph contains cycle")else :    print ("Graph does not contain cycle ")  #This code is contributed by Neelam Yadav
// C# Program to detect cycle in an undirected graphusing System;using System.Collections.Generic; // This class represents a directed graph// using adjacency list representationclass 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 contains 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 contains cycle");    }} // This code is contributed by PrinciRaj1992
Output: 
Graph contains cycle
Graph doesn't contain cycle
Complexity Analysis: 
Time Complexity: O(V+E). The program does a simple DFS Traversal of the graph which is represented using adjacency list. So the time complexity is O(V+E).
Space Complexity: O(V). To store the visited array O(V) space is required.
YouTubeGeeksforGeeks502K subscribersDetect cycle in an undirected graph | GeeksforGeeksWatch laterShareCopy linkInfoShoppingTap to unmuteIf playback doesn't begin shortly, try restarting your device.You're signed outVideos you watch may be added to the TV's watch history and influence TV recommendations. To avoid this, cancel and sign in to YouTube on your computer.CancelConfirmMore videosMore videosSwitch cameraShareInclude playlistAn error occurred while retrieving sharing information. Please try again later.Watch on0:000:000:00 / 7:20•Live•<div class="player-unavailable"><h1 class="message">An error occurred.</h1><div class="submessage"><a href="https://www.youtube.com/watch?v=6ZRhq2oFCuo" target="_blank">Try watching this video on www.youtube.com</a>, or enable JavaScript if it is disabled in your browser.</div></div>
Exercise: Can we use BFS to detect cycle in an undirected graph in O(V+E) time? What about directed graphs?Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
de_astle
princiraj1992
andrew1234
nikhil104
faraziqbal
ankitdoot
surindertarika1234
amartyaghoshgfg
Adobe
Amazon
BFS
DFS
Flipkart
graph-cycle
MakeMyTrip
Oracle
Samsung
union-find
Graph
Flipkart
Amazon
Samsung
MakeMyTrip
Oracle
Adobe
DFS
Graph
BFS
union-find
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Dijkstra's shortest path algorithm | Greedy Algo-7
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16
Disjoint Set (Or Union-Find) | Set 1 (Detect Cycle in an Undirected Graph)
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Check whether a given graph is Bipartite or not
Ford-Fulkerson Algorithm for Maximum Flow Problem
Traveling Salesman Problem (TSP) Implementation