Last Updated: 1 Jan, 2021

Cycle Detection In Undirected Graph

Moderate
Asked in companies
AmazonAdobeSamsung

Problem statement

You have been given an undirected graph with 'N' vertices and 'M' edges. The vertices are labelled from 1 to 'N'.

Your task is to find if the graph contains a cycle or not.

A path that starts from a given vertex and ends at the same vertex traversing the edges only once is called a cycle.

Example :

In the below graph, there exists a cycle between vertex 1, 2 and 3. 

Example

Note:

1. There are no parallel edges between two vertices.

2. There are no self-loops(an edge connecting the vertex to itself) in the graph.

3. The graph can be disconnected.

For Example :

Input: N = 3 , Edges =  [[1, 2], [2, 3], [1, 3]].
Output: Yes

Explanation : There are a total of 3 vertices in the graph. There is an edge between vertex 1 and 2, vertex 2 and 3 and vertex 1 and 3. So, there exists a cycle in the graph. 
Input Format:
The first line of input contains an integer 'T' which denotes the number of test cases or queries to be run. Then the test cases follow.

The first line of each test case contains two single space-separated integers ‘N’ and ‘M’ representing the total number of vertices and edges, respectively.

The next ‘M’ lines contain two single space-separated integers representing an edge of the graph.
Output Format:
For each test case, the only line of output will return “Yes” if there exists a cycle in the graph. Else print “No”.
Note:
You are not required to print the expected output, it has already been taken care of. Just implement the function.
Constraints:
1 <= T <= 10
1 <= N <= 5000
0 <= M <= min(5000, (N * (N - 1)) / 2)
1 <= edges[i][0] <= N 
1 <= edges[i][1] <= N 

Time Limit: 1 sec 

Approaches

01 Approach

There is a cycle in the graph only if there is a back edge (back edge is an edge that connects a vertex to another vertex that is discovered before it's parent) present in the graph. To detect a back edge, we will keep track of vertices that have been already visited. If we reach a vertex that is already visited and is not the parent vertex of the current vertex, then there is a cycle in the graph. 

 

Here is the complete algorithm:

  1. We create a graph using the ‘EDGES’ array and initialise an array ‘VISITED’ to keep track of the visited vertices.
  2. We iterate over all vertices of the graph and if the vertex is unvisited, we call the ‘IS_CYCLEfunction from that vertex. The ‘IS_CYCLE’ function works as follows:
    1. Mark the current vertex true in the ‘VISITED’ array.
    2. Find all the adjacent vertices of the current vertex.
      1. If an adjacent vertex is not visited
        1. Recursively call the ‘IS_CYCLE’ function for the adjacent vertex.
        2. If the recursive function returns true, then return true.
      2. Else if the adjacent vertex is already visited and is not the parent vertex of the current vertex.
        1. Return true.
    3. Finally, return false.
  3. If the ‘IS_CYLCE’ function returns true, then return “Yes”. Else return “No”.

02 Approach

In this approach, we will use breadth-first search algorithm to find the cycle in the undirected graph.

The approach is similar to the previous approach with some changes in the ‘IS_CYCLE’ function.

 

The ‘IS_CYCLE’ function will work as follows:

  1. We push the current vertex in the queue.
  2. We then run a while loop until the queue becomes empty.
    1. Pop the front vertex from the queue.
    2. We mark it true in the ‘VISITED’ array.
    3. Find all the adjacent vertices of the current vertex.
      1. If the adjacent vertex is not visited:
        1. We mark it true in the ‘VISITED’ array and push it in the queue.
      2. Else if the adjacent vertex is visited and it is not the parent vertex of the current vertex.
        1. Return true
    4. Finally, return false.

03 Approach

In this approach, we will use the union-find algorithm to find the cycle in the undirected graph. 

The main idea behind using this algorithm is that if we have two subsets that are already connected through an edge and if they get connected by another edge then they form a cycle.

 

The union-find algorithm is an algorithm that performs two useful operations on a disjoint-set data structure:

Find: Determine which subset a particular element is in. This can be used for determining if two elements are in the same subset.

Union: Join two subsets into a single subset.

We will iterate through all edges and whenever we find two vertices with the same parent we return “Yes”.

 

Here is the algorithm:

  1. We initialise two arrays ‘PARENT’ and ‘RANK’ to keep track of the parent and rank of the subsets. Here rank denotes the depth of the tree (subset).
  2. Now we will iterate through all edges of the graph:
    1. Find the parent of both vertices (say ‘PARENT1’ and ‘PARENT2’).
    2. If ‘PARENT1’ == ‘PARENT2’
      1. Return “Yes”. Here, ‘PARENT1’ == ‘PARENT2’ represents that both subsets are initially connected and now we have another edge connecting them. Hence a cycle exists.
    3. Else If ‘PARENT1’ != ‘PARENT2’
      1. Union both subsets into a single set. We are doing this because we have two subsets and an edge connecting them. Now both subsets combine and become a single subset.
  3. Finally, return “No”.