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 vertices to their degrees. 
Initially, traverse the map and store all the vertices with degree = 1 in a queue. Traverse the queue as long as it is not empty. For each node in the queue, mark it as visited, and iterate through all the nodes that are connected to it (using the adjacency list), and decrement the degree of each of those nodes by one in the map. Add all nodes whose degree becomes equal to one to the queue. At the end of this algorithm, all the nodes that are unvisited are part of the cycle.

Below is the implementation of the above approach:  

C++14

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Graph class
class Graph
{
public:
     
    // No. of vertices of graph
    int v;
 
    // Adjacency List
    vector<int> *l;
 
    Graph(int v)
    {
        this->v = v;
        this->l = new vector<int>[v];
    }
 
    void addedge(int i, int j)
    {
        l[i].push_back(j);
        l[j].push_back(i);
    }
};
 
// Function to find a cycle in the given graph if exists
void findCycle(int n, int r, Graph g)
{
    // HashMap to store the degree of each node
    unordered_map<int, int> degree;
 
    for (int i = 0; i < g.v; i++)
        degree[i] = g.l[i].size();
 
    // Array to track visited nodes
    int visited[g.v] = {0};
 
    // Queue to store the nodes of degree 1
    queue<int> q;
 
    // Continuously adding those nodes whose
    // degree is 1 to the queue
    while (true)
    {
        // Adding nodes to queue whose degree is 1
        // and is not visited
        for (int i = 0; i < degree.size(); i++)
            if (degree.at(i) == 1 and !visited[i])
                q.push(i);
 
        // If queue becomes empty then get out
        // of the continuous loop
        if (q.empty())
            break;
 
        while (!q.empty())
        {
            // Remove the front element from the queue
            int temp = q.front();
            q.pop();
 
            // Mark the removed element visited
            visited[temp] = 1;
 
            // Decrement the degree of all those nodes
            // adjacent to removed node
            for (int i = 0; i < g.l[temp].size(); i++)
            {
                int value = degree[g.l[temp][i]];
                degree[g.l[temp][i]] = --value;
            }
        }
    }
    int flag = 0;
 
    // Checking all the nodes which are not visited
    // i.e. they are part of the cycle
    for (int i = 0; i < g.v; i++)
        if (visited[i] == 0)
            flag = 1;
 
    if (flag == 0)
        cout << "-1";
    else
    {
        for (int i = 0; i < g.v; i++)
            if (visited[i] == 0)
                cout << i << " ";
    }
}
 
// Driver Code
int main()
{
    // No of nodes
    int n = 5;
 
    // No of edges
    int e = 5;
    Graph g(n);
 
    g.addedge(0, 1);
    g.addedge(0, 2);
    g.addedge(0, 3);
    g.addedge(1, 2);
    g.addedge(3, 4);
 
    findCycle(n, e, g);
    return 0;
}
 
// This code is contributed by
// sanjeev2552

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
 
// Graph class
class Graph {
 
    // No. of vertices of graph
    int v;
 
    // Adjacency List
    LinkedList l[];
 
    Graph(int v)
    {
        this.v = v;
        this.l = new LinkedList[v];
        for (int i = 0; i < v; i++) {
            l[i] = new LinkedList();
        }
    }
    void addedge(int i, int j)
    {
        l[i].add(j);
        l[j].add(i);
    }
}
 
class GFG {
 
    // Function to find a cycle in the given graph if exists
    static void findCycle(int n, int e, Graph g)
    {
 
        // HashMap to store the degree of each node
        HashMap degree = new HashMap();
 
        for (int i = 0; i < g.l.length; i++)
            degree.put(i, g.l[i].size());
 
        // Array to track visited nodes
        int visited[] = new int[g.v];
 
        // Initially all nodes are not visited
        for (int i = 0; i < visited.length; i++)
            visited[i] = 0;
 
        // Queue to store the nodes of degree 1
        LinkedList q = new LinkedList();
 
        // Continuously adding those nodes whose
        // degree is 1 to the queue
        while (true) {
 
            // Adding nodes to queue whose degree is 1
            // and is not visited
 
            for (int i = 0; i < degree.size(); i++)
                if ((int)degree.get(i) == 1 && visited[i] == 0)
                    q.add(i);
 
            // If queue becomes empty then get out
            // of the continuous loop
            if (q.isEmpty())
                break;
 
            while (!q.isEmpty()) {
 
                // Remove the front element from the queue
                int temp = (int)q.remove();
 
                // Mark the removed element visited
                visited[temp] = 1;
 
                // Decrement the degree of all those nodes
                // adjacent to removed node
                for (int i = 0; i < g.l[temp].size(); i++) {
                    int value = (int)degree.get((int)g.l[temp].get(i));
                    degree.replace(g.l[temp].get(i), --value);
                }
            }
        }
 
        int flag = 0;
 
        // Checking all the nodes which are not visited
        // i.e. they are part of the cycle
        for (int i = 0; i < visited.length; i++)
            if (visited[i] == 0)
                flag = 1;
 
        if (flag == 0)
            System.out.print("-1");
        else {
            for (int i = 0; i < visited.length; i++)
                if (visited[i] == 0)
                    System.out.print(i + " ");
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        // No of nodes
        int n = 5;
 
        // No of edges
        int e = 5;
        Graph g = new Graph(n);
 
        g.addedge(0, 1);
        g.addedge(0, 2);
        g.addedge(0, 3);
        g.addedge(1, 2);
        g.addedge(3, 4);
 
        findCycle(n, e, g);
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach
 
# Graph class
class Graph:
    def __init__(self, v):
 
        # No. of vertices of graph
        self.v = v
 
        # Adjacency List
        self.l = [0] * v
        for i in range(self.v):
            self.l[i] = []
 
    def addedge(self, i: int, j: int):
        self.l[i].append(j)
        self.l[j].append(i)
 
# Function to find a cycle in the given graph if exists
def findCycle(n: int, e: int, g: Graph) -> None:
 
    # HashMap to store the degree of each node
    degree = dict()
 
    for i in range(len(g.l)):
        degree[i] = len(g.l[i])
 
    # Array to track visited nodes
    visited = [0] * g.v
 
    # Initially all nodes are not visited
    for i in range(len(visited)):
        visited[i] = 0
 
    # Queue to store the nodes of degree 1
    q = list()
 
    # Continuously adding those nodes whose
    # degree is 1 to the queue
    while True:
 
        # Adding nodes to queue whose degree is 1
        # and is not visited
        for i in range(len(degree)):
            if degree[i] == 1 and visited[i] == 0:
                q.append(i)
 
        # If queue becomes empty then get out
        # of the continuous loop
        if len(q) == 0:
            break
 
        while q:
 
            # Remove the front element from the queue
            temp = q.pop()
 
            # Mark the removed element visited
            visited[temp] = 1
 
            # Decrement the degree of all those nodes
            # adjacent to removed node
            for i in range(len(g.l[temp])):
                value = degree[g.l[temp][i]]
                degree[g.l[temp][i]] = value - 1
 
    flag = 0
 
    # Checking all the nodes which are not visited
    # i.e. they are part of the cycle
    for i in range(len(visited)):
        if visited[i] == 0:
            flag = 1
 
    if flag == 0:
        print("-1")
    else:
        for i in range(len(visited)):
            if visited[i] == 0:
                print(i, end = " ")
 
# Driver Code
if __name__ == "__main__":
 
    # No of nodes
    n = 5
 
    # No of edges
    e = 5
    g = Graph(n)
 
    g.addedge(0, 1)
    g.addedge(0, 2)
    g.addedge(0, 3)
    g.addedge(1, 2)
    g.addedge(3, 4)
 
    findCycle(n, e, g)
 
# This code is contributed by
# sanjeev2552

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
using System.Collections.Generic;
 
// Graph class
public class Graph
{
     
    // No. of vertices of graph
    public int v;
     
    // Adjacency List
    public  List<int> []l;
     
    public Graph(int v)
    {
        this.v = v;
        this.l = new List<int>[v];
        for(int i = 0; i < v; i++)
        {
            l[i] = new List<int>();
        }
    }
    public void addedge(int i, int j)
    {
        l[i].Add(j);
        l[j].Add(i);
    }
}
 
class GFG{
 
// Function to find a cycle in the
// given graph if exists
static void findCycle(int n, int e, Graph g)
{
     
    // Dictionary to store the degree of each node
    Dictionary<int,
               int> degree = new Dictionary<int,
                                            int>();
 
    for(int i = 0; i < g.l.Length; i++)
        degree.Add(i, g.l[i].Count);
 
    // Array to track visited nodes
    int []visited = new int[g.v];
 
    // Initially all nodes are not visited
    for(int i = 0; i < visited.Length; i++)
        visited[i] = 0;
 
    // Queue to store the nodes of degree 1
    List<int> q = new List<int>();
 
    // Continuously adding those nodes whose
    // degree is 1 to the queue
    while (true)
    {
         
        // Adding nodes to queue whose degree is 1
        // and is not visited
        for(int i = 0; i < degree.Count; i++)
            if ((int)degree[i] == 1 && visited[i] == 0)
                q.Add(i);
 
        // If queue becomes empty then get out
        // of the continuous loop
        if (q.Count!=0)
            break;
 
        while (q.Count != 0)
        {
             
            // Remove the front element from the queue
            int temp = q[0];   
            q.RemoveAt(0);
 
            // Mark the removed element visited
            visited[temp] = 1;
 
            // Decrement the degree of all those nodes
            // adjacent to removed node
            for(int i = 0; i < g.l[temp].Count; i++)
            {
                int value = (int)degree[(int)g.l[temp][i]];
                degree[g.l[temp][i]] = value -= 1;
            }
        }
    }
 
    int flag = 0;
 
    // Checking all the nodes which are not visited
    // i.e. they are part of the cycle
    for(int i = 0; i < visited.Length; i++)
        if (visited[i] == 0)
            flag = 1;
 
    if (flag == 0)
        Console.Write("-1");
    else
    {
        for(int i = 0; i < visited.Length-2; i++)
            if (visited[i] == 0)
                Console.Write(i + " ");
    }
}
 
// Driver code
public static void Main(String[] args)
{
     
    // No of nodes
    int n = 5;
 
    // No of edges
    int e = 5;
    Graph g = new Graph(n);
 
    g.addedge(0, 1);
    g.addedge(0, 2);
    g.addedge(0, 3);
    g.addedge(1, 2);
    g.addedge(3, 4);
 
    findCycle(n, e, g);
}
}
 
// This code is contributed by Princi Singh

chevron_right


Output: 

0 1 2




 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : sanjeev2552, princi singh

Article Tags :
Practice Tags :


3


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.