Given an undirected graph, print all the vertices that form cycles in it.
Pre-requisite: Detect Cycle in a directed graph using colors
Undirected Graph
In the above diagram, the cycles have been marked with dark green color. The output for the above will be
1st cycle: 3 5 4 6
2nd cycle: 5 6 10 9
3rd cycle: 11 12 13
Approach: Using the graph coloring method, mark all the vertex of the different cycles with unique numbers. Once the graph traversal is completed, push all the similar marked numbers to an adjacency list and print the adjacency list accordingly. Given below is the algorithm:
- Insert the edges into an adjacency list.
- Call the DFS function which uses the coloring method to mark the vertex.
- Whenever there is a partially visited vertex, backtrack till the current vertex is reached and store them into a vector. Once all the vertices of this cycle are stored into the vector, store this vector into our global cycle answer vector and increase the cycle number.
- Once DFS is completed, iterate into our global cycle answer vector and print the vertex cycle-number wise.
Below is the implementation of the above approach:
C++
// C++ program to print all the cycles// in an undirected graph#include <bits/stdc++.h>using namespace std;const int N = 100000;// variables to be used// in both functionsvector<int> graph[N];vector<vector<int>> cycles;// Function to mark the vertex with// different colors for different cyclesvoid dfs_cycle(int u, int p, int color[], int par[], int& cyclenumber){ // already (completely) visited vertex. if (color[u] == 2) { return; } // seen vertex, but was not completely visited -> cycle detected. // backtrack based on parents to find the complete cycle. if (color[u] == 1) { vector<int> v; cyclenumber++; int cur = p; v.push_back(cur); // backtrack the vertex which are // in the current cycle thats found while (cur != u) { cur = par[cur]; v.push_back(cur); } cycles.push_back(v); return; } par[u] = p; // partially visited. color[u] = 1; // simple dfs on graph for (int v : graph[u]) { // if it has not been visited previously if (v == par[u]) { continue; } dfs_cycle(v, u, color, par, cyclenumber); } // completely visited. color[u] = 2;}// add the edges to the graphvoid addEdge(int u, int v){ graph[u].push_back(v); graph[v].push_back(u);}// Function to print the cyclesvoid printCycles(int& cyclenumber){ // print all the vertex with same cycle for (int i = 0; i < cyclenumber; i++) { // Print the i-th cycle cout << "Cycle Number " << i + 1 << ": "; for (int x : cycles[i]) cout << x << " "; cout << endl; }}// Driver Codeint main(){ // add edges addEdge(1, 2); addEdge(2, 3); addEdge(3, 4); addEdge(4, 6); addEdge(4, 7); addEdge(5, 6); addEdge(3, 5); addEdge(7, 8); addEdge(6, 10); addEdge(5, 9); addEdge(10, 9); addEdge(10, 11); addEdge(11, 12); addEdge(11, 13); addEdge(12, 13); // arrays required to color the // graph, store the parent of node int color[N]; int par[N]; // store the numbers of cycle int cyclenumber = 0; int edges = 6; // call DFS to mark the cycles dfs_cycle(1, 0, color, par, cyclenumber); // function to print the cycles printCycles(cyclenumber);} |
Java
// Java program to print all the cycles // in an undirected graph import java.util.*;class GFG { static final int N = 100000; // variables to be used // in both functions @SuppressWarnings("unchecked") static Vector<Integer>[] graph = new Vector[N]; @SuppressWarnings("unchecked") static Vector<Integer>[] cycles = new Vector[N]; static int cyclenumber; // Function to mark the vertex with // different colors for different cycles static void dfs_cycle(int u, int p, int[] color,int[] par) { // already (completely) visited vertex. if (color[u] == 2) { return; } // seen vertex, but was not completely visited -> cycle detected. // backtrack based on parents to find the complete cycle. if (color[u] == 1) { Vector<Integer> v = new Vector<Integer>(); int cur = p; v.add(cur); // backtrack the vertex which are // in the current cycle thats found while (cur != u) { cur = par[cur]; v.add(cur); } cycles[cyclenumber] = v; cyclenumber++; return; } par[u] = p; // partially visited. color[u] = 1; // simple dfs on graph for (int v : graph[u]) { // if it has not been visited previously if (v == par[u]) { continue; } dfs_cycle(v, u, color, par); } // completely visited. color[u] = 2; } // add the edges to the graph static void addEdge(int u, int v) { graph[u].add(v); graph[v].add(u); } // Function to print the cycles static void printCycles() { // print all the vertex with same cycle for (int i = 0; i < cyclenumber; i++) { // Print the i-th cycle System.out.printf("Cycle Number %d: ", i + 1); for (int x : cycles[i]) System.out.printf("%d ", x); System.out.println(); } } // Driver Code public static void main(String[] args) { for (int i = 0; i < N; i++) { graph[i] = new Vector<>(); cycles[i] = new Vector<>(); } // add edges addEdge(1, 2); addEdge(2, 3); addEdge(3, 4); addEdge(4, 6); addEdge(4, 7); addEdge(5, 6); addEdge(3, 5); addEdge(7, 8); addEdge(6, 10); addEdge(5, 9); addEdge(10, 9); addEdge(10, 11); addEdge(11, 12); addEdge(11, 13); addEdge(12, 13); // arrays required to color the // graph, store the parent of node int[] color = new int[N]; int[] par = new int[N]; // mark with unique numbers int[] mark = new int[N]; // store the numbers of cycle cyclenumber = 0; // call DFS to mark the cycles dfs_cycle(1, 0, color, par); // function to print the cycles printCycles(); }} |
Python3
# Python3 program to print all the cycles# in an undirected graphN = 100000# variables to be used# in both functionsgraph = [[] for i in range(N)]cycles = [[] for i in range(N)]# Function to mark the vertex with# different colors for different cyclesdef dfs_cycle(u, p, color: list, par: list): global cyclenumber # already (completely) visited vertex. if color[u] == 2: return # seen vertex, but was not # completely visited -> cycle detected. # backtrack based on parents to # find the complete cycle. if color[u] == 1: v = [] cur = p v.append(cur) # backtrack the vertex which are # in the current cycle thats found while cur != u: cur = par[cur] v.append(cur) cycles[cyclenumber] = v cyclenumber += 1 return par[u] = p # partially visited. color[u] = 1 # simple dfs on graph for v in graph[u]: # if it has not been visited previously if v == par[u]: continue dfs_cycle(v, u, color, par) # completely visited. color[u] = 2# add the edges to the graphdef addEdge(u, v): graph[u].append(v) graph[v].append(u)# Function to print the cyclesdef printCycles(): # print all the vertex with same cycle for i in range(0, cyclenumber): # Print the i-th cycle print("Cycle Number %d:" % (i+1), end = " ") for x in cycles[i]: print(x, end = " ") print()# Driver Codeif __name__ == "__main__": # add edges addEdge(1, 2) addEdge(2, 3) addEdge(3, 4) addEdge(4, 6) addEdge(4, 7) addEdge(5, 6) addEdge(3, 5) addEdge(7, 8) addEdge(6, 10) addEdge(5, 9) addEdge(10, 9) addEdge(10, 11) addEdge(11, 12) addEdge(11, 13) addEdge(12, 13) # arrays required to color the # graph, store the parent of node color = [0] * N par = [0] * N # store the numbers of cycle cyclenumber = 0 # call DFS to mark the cycles dfs_cycle(1, 0, color, par) # function to print the cycles printCycles() |
C#
// C# program to print all// the cycles in an undirected // graph using System;using System.Collections.Generic;class GFG{static readonly int N = 100000;// variables to be used// in both functionsstatic List<int>[] graph = new List<int>[N];static List<int>[] cycles = new List<int>[N];static int cyclenumber;// Function to mark the vertex with// different colors for different cyclesstatic void dfs_cycle(int u, int p, int[] color, int[] par){ // already (completely) // visited vertex. if (color[u] == 2) { return; } // seen vertex, but was not // completely visited -> cycle // detected. backtrack based on // parents to find the complete // cycle. if (color[u] == 1) { List<int> v = new List<int>(); int cur = p; v.Add(cur); // backtrack the vertex which // are in the current cycle // thats found while (cur != u) { cur = par[cur]; v.Add(cur); } cycles[cyclenumber] = v; cyclenumber++; return; } par[u] = p; // partially visited. color[u] = 1; // simple dfs on graph foreach (int v in graph[u]) { // if it has not been // visited previously if (v == par[u]) { continue; } dfs_cycle(v, u, color, par); } // completely visited. color[u] = 2;}// add the edges to the // graphstatic void addEdge(int u, int v) { graph[u].Add(v); graph[v].Add(u);}// Function to print the cyclesstatic void printCycles(){ // print all the vertex with // same cycle for (int i = 0; i < cyclenumber; i++) { // Print the i-th cycle Console.Write("Cycle Number " + (i+1) + ":"); foreach (int x in cycles[i]) Console.Write(" " + x); Console.WriteLine(); }}// Driver Codepublic static void Main(String[] args){ for (int i = 0; i < N; i++) { graph[i] = new List<int>(); cycles[i] = new List<int>(); } // add edges addEdge(1, 2); addEdge(2, 3); addEdge(3, 4); addEdge(4, 6); addEdge(4, 7); addEdge(5, 6); addEdge(3, 5); addEdge(7, 8); addEdge(6, 10); addEdge(5, 9); addEdge(10, 9); addEdge(10, 11); addEdge(11, 12); addEdge(11, 13); addEdge(12, 13); // arrays required to color // the graph, store the parent // of node int[] color = new int[N]; int[] par = new int[N]; // store the numbers of cycle cyclenumber = 0; // call DFS to mark // the cycles dfs_cycle(1, 0, color, par); // function to print the cycles printCycles();}} |
Javascript
<script>// JavaScript program to print all// the cycles in an undirected // graph var N = 100000;// variables to be used// in both functionsvar graph = Array.from(Array(N), ()=>Array());var cycles = Array.from(Array(N), ()=>Array()); var cyclenumber = 0;// Function to mark the vertex with// different colors for different cyclesfunction dfs_cycle(u, p, color, par){ // already (completely) // visited vertex. if (color[u] == 2) { return; } // seen vertex, but was not // completely visited -> cycle // detected. backtrack based on // parents to find the complete // cycle. if (color[u] == 1) { var v = []; var cur = p; v.push(cur); // backtrack the vertex which // are in the current cycle // thats found while (cur != u) { cur = par[cur]; v.push(vur); } cycles[cyclenumber] = v; cyclenumber++; return; } par[u] = p; // partially visited. color[u] = 1; // simple dfs on graph for(var v of graph[u]) { // if it has not been // visited previously if (v == par[u]) { continue; } dfs_cycle(v, u, color, par); } // completely visited. color[u] = 2;}// add the edges to the // graphfunction addEdge(u, v) { graph[u].push(v); graph[v].push(u);}// Function to print the cyclesfunction printCycles(){ // print all the vertex with // same cycle for (var i = 0; i < cyclenumber; i++) { // Print the i-th cycle document.write("Cycle Number " + (i+1) + ":"); for(var x of cycles[i]) document.write(" " + x); document.write("<br>"); }}// Driver Code// add edgesaddEdge(1, 2);addEdge(2, 3);addEdge(3, 4);addEdge(4, 6);addEdge(4, 7);addEdge(5, 6);addEdge(3, 5);addEdge(7, 8);addEdge(6, 10);addEdge(5, 9);addEdge(10, 9);addEdge(10, 11);addEdge(11, 12);addEdge(11, 13);addEdge(12, 13);// arrays required to color // the graph, store the parent // of nodevar color = Array(N).fill(0);var par = Array(N).fill(0);// store the numbers of cyclecyclenumber = 0;// call DFS to mark // the cyclesdfs_cycle(1, 0, color, par);// function to print the cyclesprintCycles();</script> |
Cycle Number 1: 5 6 4 3 Cycle Number 2: 10 9 5 6 Cycle Number 3: 13 12 11
Time Complexity: O(N + M), where N is the number of vertexes and M is the number of edges.
Auxiliary Space: O(N + M)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
