Find any simple cycle in an undirected unweighted Graph - GeeksforGeeks

22 Jun, 2021
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 to the following image: 
The graph in the above picture explains how the cycle 1 -> 2 -> 3 -> 4 -> 1 isn’t a simple cycle because, it can be broken into 2 simple cycles 1 -> 3 -> 4 -> 1 and 1 -> 2 -> 3 -> 1. 
Examples: 
Input: edges[]  = {(1, 2), (2, 3), (2, 4), (3, 4)} 
Output: 2 => 3 => 4 => 2Explanation:This graph has only one cycle of length 3 which is a simple cycle.
Input: edges[] = {(1, 2), (2, 3), (3, 4), (1, 4), (1, 3)} 
Output: 1 => 3 => 4 => 1
Approach:  The idea is to check that if the graph contains a cycle or not. This can be done by simply using a DFS. Now, if the graph contains a cycle, we can get the end vertices (say a and b) of that cycle from the DFS itself. Now, if we run a BFS from a to b (ignoring the direct edge between a and b), we’ll be able to get the shortest path from a to b, which will give us the path of the shortest cycle containing the points a and b. The path can be easily tracked by using a parent array. This shortest cycle will be a simple cycle. 
We can prove this using contradiction. Let’s say there exists another simple cycle inside this cycle. This means the inner simple cycle will have a shorter length and, hence it can be said that there’s a shorter path from a to b. But we have found the shortest path from a to b using BFS. Hence, no shorter path exists and the found path is the shortest. So, no inner cycles can exist inside of the cycle we’ve found. Hence, this cycle is a simple cycle.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ implementation to find the// simple cycle in the given path #include <bits/stdc++.h>using namespace std;#define MAXN 1005 // Declaration of the Graphvector<vector<int> > adj(MAXN); // Declaration of visited arrayvector<bool> vis(MAXN);int a, b; // Function to add edges// connecting 'a' and 'b'// to the graphvoid addedge(int a, int b){    adj[a].push_back(b);    adj[b].push_back(a);} // Function to detect if the// graph contains a cycle or notbool detect_cycle(int node, int par){    // Marking the current node visited    vis[node] = 1;    // Traversing to the childs    // of the current node    // Simple DFS approach    for (auto child : adj[node]) {        if (vis[child] == 0) {            if (detect_cycle(child, node))                return true;        }         // Checking for a back-edge        else if (child != par) {            // A cycle is detected            // Marking the end-vertices            // of the cycle            a = child;            b = node;            return true;        }    }    return false;} vector<int> simple_cycle; // Function to get the simple cycle from the// end-vertices of the cycle we found from DFSvoid find_simple_cycle(int a, int b){    // Parent array to get the path    vector<int> par(MAXN, -1);     // Queue for BFS    queue<int> q;    q.push(a);    bool ok = true;    while (!q.empty()) {        int node = q.front();        q.pop();        vis[node] = 1;        for (auto child : adj[node]) {            if (node == a && child == b)                // Ignoring the direct edge                // between a and b                continue;             if (vis[child] == 0) {                // Updating the parent array                par[child] = node;                 if (child == b) {                    // If b is reached,                    // we've found the                    // shortest path from                    // a to b already                    ok = false;                    break;                }                q.push(child);                vis[child] = 1;            }        }        // If required task is done        if (ok == false)            break;    }     // Cycle starting from a    simple_cycle.push_back(a);    int x = b;     // Until we reach a again    while (x != a) {        simple_cycle.push_back(x);        x = par[x];    }} // Driver Codeint main(){     // Creating the graph    addedge(1, 2);    addedge(2, 3);    addedge(3, 4);    addedge(4, 1);    addedge(1, 3);     if (detect_cycle(1, -1) == true) {        // If cycle is present         // Resetting the visited array        // for simple cycle finding        vis = vector<bool>(MAXN, false);        find_simple_cycle(a, b);         // Printing the simple cycle        cout << "A simple cycle: ";        for (auto& node : simple_cycle) {            cout << node << " => ";        }        cout << a;        cout << "\n";    }    else {        cout << "The Graph doesn't "             << "contain a cycle.\n";    }     return 0;}
// Java implementation to// find the simple cycle// in the given pathimport java.util.*;class GFG{   static final int MAXN = 1005; // Declaration of the// Graphstatic Vector<Integer> []adj =              new Vector[MAXN]; // Declaration of visited// arraystatic boolean []vis =       new boolean[MAXN];static int a, b; // Function to add edges// connecting 'a' and 'b'// to the graphstatic void addedge(int a,                    int b){  adj[a].add(b);  adj[b].add(a);} // Function to detect if the// graph contains a cycle or notstatic boolean detect_cycle(int node,                            int par){  // Marking the current  // node visited  vis[node] = true;     // Traversing to the childs  // of the current node  // Simple DFS approach  for (int child : adj[node])  {    if (vis[child] == false)    {      if (detect_cycle(child,                       node))        return true;    }     // Checking for a back-edge    else if (child != par)    {      // A cycle is detected      // Marking the end-vertices      // of the cycle      a = child;      b = node;      return true;    }  }  return false;} static Vector<Integer> simple_cycle =              new Vector<>(); // Function to get the simple// cycle from the end-vertices//of the cycle we found from DFSstatic void find_simple_cycle(int a,                              int b){  // Parent array to get the path  int []par = new int[MAXN];   // Queue for BFS  Queue<Integer> q =        new LinkedList<>();  q.add(a);  boolean ok = true;     while (!q.isEmpty())  {    int node = q.peek();    q.remove();    vis[node] = true;         for (int child : adj[node])    {      if (node == a &&          child == b)        // Ignoring the direct edge        // between a and b        continue;       if (vis[child] == false)      {        // Updating the parent        // array        par[child] = node;         if (child == b)        {          // If b is reached,          // we've found the          // shortest path from          // a to b already          ok = false;          break;        }        q.add(child);        vis[child] = true;      }    }    // If required task    // is done    if (ok == false)      break;  }   // Cycle starting from a  simple_cycle.add(a);  int x = b;   // Until we reach  // a again  while (x != a)  {    simple_cycle.add(x);    x = par[x];  }} // Driver Codepublic static void main(String[] args){  for (int i = 0; i < adj.length; i++)    adj[i] = new Vector<Integer>();     // Creating the graph  addedge(1, 2);  addedge(2, 3);  addedge(3, 4);  addedge(4, 1);  addedge(1, 3);   if (detect_cycle(1, -1) == true)  {    // If cycle is present    // Resetting the visited array    // for simple cycle finding    Arrays.fill(vis, false);    find_simple_cycle(a, b);     // Printing the simple cycle    System.out.print("A simple cycle: ");         for (int node : simple_cycle)    {      System.out.print(node + " => ");    }    System.out.print(a);    System.out.print("\n");  }  else  {    System.out.print("The Graph doesn't " +                     "contain a cycle.\n");  }}} // This code is contributed by shikhasingrajput
# Python3 implementation to find the# simple cycle in the given path MAXN = 1005  # Declaration of the Graphadj = [[] for i in range(MAXN)]  # Declaration of visited arrayvis = [False for i in range(MAXN)]aa = 0bb = 0  # Function to add edges# connecting 'a' and 'b'# to the graphdef addedge(a, b):     adj[a].append(b);    adj[b].append(a);      # Function to detect if the# graph contains a cycle or notdef detect_cycle(node, par):    global aa, bb     # Marking the current node visited    vis[node] = True;     # Traversing to the childs    # of the current node    # Simple DFS approach    for child in adj[node]:                 if (vis[child] == False):            if (detect_cycle(child, node)):                return True;          # Checking for a back-edge        elif (child != par):             # A cycle is detected            # Marking the end-vertices            # of the cycle            aa = child;            bb = node;            return True;             return False;  simple_cycle = []  # Function to get the simple cycle from the# end-vertices of the cycle we found from DFSdef find_simple_cycle(a, b):     # Parent array to get the path    par = [0 for i in range(MAXN)]      # Queue for BFS    q = []    q.append(a);    ok = True;    while(len(q) != 0):                 node = q[0];        q.pop(0);        vis[node] = True;                 for child in adj[node]:                         if (node == a and child == b):                                 # Ignoring the direct edge                # between a and b                continue;              if (vis[child] == False):                                 # Updating the parent array                par[child] = node;                  if (child == b):                                         # If b is reached,                    # we've found the                    # shortest path from                    # a to b already                    ok = False;                    break;                             q.append(child);                vis[child] = True;         # If required task is done        if (ok == False):            break;      # Cycle starting from a    simple_cycle.append(a);    x = b;      # Until we reach a again    while (x != a):        simple_cycle.append(x);        x = par[x];      # Driver Codeif __name__=='__main__':         # Creating the graph    addedge(1, 2);    addedge(2, 3);    addedge(3, 4);    addedge(4, 1);    addedge(1, 3);      if (detect_cycle(1, -1) == True):        # If cycle is present          # Resetting the visited array        # for simple cycle finding        for i in range(MAXN):            vis[i] = False        find_simple_cycle(aa, bb);         # Printing the simple cycle        print("A simple cycle: ", end = '')        for node in simple_cycle:            print(node, end = " => ")        print(aa)     else:        print("The Graph doesn't contain a cycle.")         # This code is contributed by rutvik_56
// C# implementation to// find the simple cycle// in the given pathusing System;using System.Collections.Generic; class GFG{   static readonly int MAXN = 1005;   // Declaration of the// Graphstatic List<int> []adj = new List<int>[MAXN];   // Declaration of visited// arraystatic bool []vis = new bool[MAXN];   static int a, b; // Function to add edges// connecting 'a' and 'b'// to the graphstatic void addedge(int a, int b){  adj[a].Add(b);  adj[b].Add(a);} // Function to detect if the// graph contains a cycle or notstatic bool detect_cycle(int node,                         int par){     // Marking the current  // node visited  vis[node] = true;     // Traversing to the childs  // of the current node  // Simple DFS approach  foreach(int child in adj[node])  {    if (vis[child] == false)    {      if (detect_cycle(child,                       node))        return true;    }     // Checking for a back-edge    else if (child != par)    {             // A cycle is detected      // Marking the end-vertices      // of the cycle      a = child;      b = node;      return true;    }  }  return false;} static List<int> simple_cycle = new List<int>();   // Function to get the simple// cycle from the end-vertices//of the cycle we found from DFSstatic void find_simple_cycle(int a,                              int b){     // Parent array to get the path  int []par = new int[MAXN];   // Queue for BFS  Queue<int> q = new Queue<int>();     q.Enqueue(a);  bool ok = true;     while (q.Count != 0)  {    int node = q.Peek();    q.Dequeue();    vis[node] = true;         foreach(int child in adj[node])    {      if (node == a &&          child == b)                 // Ignoring the direct edge        // between a and b        continue;       if (vis[child] == false)      {                 // Updating the parent        // array        par[child] = node;         if (child == b)        {                     // If b is reached,          // we've found the          // shortest path from          // a to b already          ok = false;          break;        }        q.Enqueue(child);        vis[child] = true;      }    }         // If required task    // is done    if (ok == false)      break;  }   // Cycle starting from a  simple_cycle.Add(a);  int x = b;   // Until we reach  // a again  while (x != a)  {    simple_cycle.Add(x);    x = par[x];  }} // Driver Codepublic static void Main(String[] args){  for(int i = 0; i < adj.Length; i++)    adj[i] = new List<int>();     // Creating the graph  addedge(1, 2);  addedge(2, 3);  addedge(3, 4);  addedge(4, 1);  addedge(1, 3);   if (detect_cycle(1, -1) == true)  {         // If cycle is present    // Resetting the visited array    // for simple cycle finding    for(int i = 0; i < vis.Length; i++)        vis[i] = false;         find_simple_cycle(a, b);     // Printing the simple cycle    Console.Write("A simple cycle: ");         foreach(int node in simple_cycle)    {      Console.Write(node + " => ");    }    Console.Write(a);    Console.Write("\n");  }  else  {    Console.Write("The Graph doesn't " +                  "contain a cycle.\n");  }}} // This code is contributed by gauravrajput1
<script> // Javascript implementation to// find the simple cycle// in the given path var MAXN = 1005;   // Declaration of the// Graphvar adj = Array.from(Array(MAXN), ()=>Array());   // Declaration of visited// arrayvar vis = Array(MAXN).fill(false);   var a, b; // Function to add edges// connecting 'a' and 'b'// to the graphfunction addedge(a, b){  adj[a].push(b);  adj[b].push(a);} // Function to detect if the// graph contains a cycle or notfunction detect_cycle(node, par){     // Marking the current  // node visited  vis[node] = true;     // Traversing to the childs  // of the current node  // Simple DFS approach  for(var child of adj[node])  {    if (vis[child] == false)    {      if (detect_cycle(child,                       node))        return true;    }     // Checking for a back-edge    else if (child != par)    {             // A cycle is detected      // Marking the end-vertices      // of the cycle      a = child;      b = node;      return true;    }  }  return false;} var simple_cycle = [];   // Function to get the simple// cycle from the end-vertices//of the cycle we found from DFSfunction find_simple_cycle(a, b){     // Parent array to get the path  var par = Array(MAXN);   // Queue for BFS  var q = [];     q.push(a);  var ok = true;     while (q.length != 0)  {    var node = q[0];    q.shift();    vis[node] = true;         for(var child of adj[node])    {      if (node == a &&          child == b)                 // Ignoring the direct edge        // between a and b        continue;       if (vis[child] == false)      {                 // Updating the parent        // array        par[child] = node;         if (child == b)        {                     // If b is reached,          // we've found the          // shortest path from          // a to b already          ok = false;          break;        }        q.push(child);        vis[child] = true;      }    }         // If required task    // is done    if (ok == false)      break;  }   // Cycle starting from a  simple_cycle.push(a);  var x = b;   // Until we reach  // a again  while (x != a)  {    simple_cycle.push(x);    x = par[x];  }} // Driver Code // Creating the graphaddedge(1, 2);addedge(2, 3);addedge(3, 4);addedge(4, 1);addedge(1, 3); if (detect_cycle(1, -1) == true){     // If cycle is present  // Resetting the visited array  // for simple cycle finding  for(var i = 0; i < vis.length; i++)      vis[i] = false;     find_simple_cycle(a, b);  // Printing the simple cycle  document.write("A simple cycle: ");     for(var node of simple_cycle)  {    document.write(node + " => ");  }  document.write(a);  document.write("<br>");}else{  document.write("The Graph doesn't " +                "contain a cycle.<br>");}  </script>
A simple cycle: 1 => 4 => 3 => 1
 
shikhasingrajput
GauravRajput1
rutvik_56
famously
BFS
DFS
graph-cycle
Competitive Programming
Graph
Tree
DFS
Graph
Tree
BFS
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Shortest path in a directed graph by Dijkstra’s algorithm
Breadth First Traversal ( BFS ) on a 2D array
Multistage Graph (Shortest Path)
Runtime Errors
Maximum LCM among all pairs (i, j) from the given Array
Breadth First Search or BFS for a Graph
Dijkstra's shortest path algorithm | Greedy Algo-7
Depth First Search or DFS for a Graph
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5