Detect cycle in an undirected graph using BFS (original) (raw)

Last Updated : 04 Apr, 2025

Try it on GfG Practice redirect icon

Given an undirected graph, the task is to determine if **cycle is present in it or not.

**Examples:

**Input: V = 5, edges[][] = [[0, 1], [0, 2], [0, 3], [1, 2], [3, 4]]

Detect-Cycle-in-Undirected-Graph-2

Undirected Graph with 5 Node

**Output: true
**Explanation: _The diagram clearly shows a cycle 0 → 2 → 1 → 0.

**Input: V = 4, edges[][] = [[0, 1], [1, 2], [2, 3]]

Detect-Cycle-in-Undirected-Graph--1

Undirected graph with 4 Node

**Output: false

**Approach:

The idea is to use BFS to detect a cycle in an undirected graph. We start BFS for all components of the graph and check if a node has been visited earlier, ensuring that we **do not consider the parent node of the current node while making this check. If we encounter a visited node that is not the parent, a **cycle exists in the graph. Otherwise, we continue BFS by marking the node as visited and inserting it into the queue.

Step by step approach:

  1. **Initialize a visited array of size n (number of nodes) to false.
  2. **Iterate through all nodes from 0 to n-1. If a node is not visited, start BFS.
  3. **Push the node into the queue with its parent set to -1.
  4. **Perform BFS:
    • Pop a node from the queue.
    • Traverse all its adjacent nodes.
    • If an adjacent node is visited and **is not the parent, return true (cycle detected).
    • Otherwise, if the adjacent node is not visited, mark it as visited and push it into the queue with the current node as its parent.
  5. If no cycle is found after checking all components, return false.

**Implementation:

C++ `

#include <bits/stdc++.h> using namespace std;

// Function to perform BFS from node start bool bfs(int start, vector<vector>& adj, vector& visited) { queue<pair<int, int>> q; q.push({start, -1}); visited[start] = true;

while (!q.empty()) {
    int node = q.front().first;
    int parent = q.front().second;
    q.pop();

    for (int neighbor : adj[node]) {

        if (!visited[neighbor]) {
            visited[neighbor] = true;
            q.push({neighbor, node});
        } 
        else if (neighbor != parent) {
            return true;
        }
    }
}
return false;

}

vector<vector> constructadj(int V, vector<vector> &edges){

vector<vector<int>> adj(V);
for (auto it : edges)
{
    adj[it[0]].push_back(it[1]);
    adj[it[1]].push_back(it[0]);
}

return adj;

}

bool isCycle(int V, vector<vector>& edges) {

vector<vector<int>> adj = constructadj(V, edges);
vector<bool> visited(V, false);

for (int i = 0; i < V; i++) {
    
    if (!visited[i]) {
        if (bfs(i, adj, visited)) {
            return true;
        }
    }
}

// If no cycle is found
return false;

}

int main() { vector<vector> edges = {{0, 1}, {0, 2}, {0, 3}, {1, 2}, {3, 4}}; int V = 5;

isCycle(V,edges) ? cout<<"true": cout<<"false";

return 0;

}

Java

import java.util.*;

public class CycleDetection {

// Function to perform BFS from a start node
static boolean bfs(int start, List<Integer>[] adj,
                   boolean[] visited)
{
    Queue<int[]> q = new LinkedList<>();
    q.offer(new int[] { start, -1 });
    visited[start] = true;

    while (!q.isEmpty()) {
        int[] front = q.poll();
        int node = front[0];
        int parent = front[1];

        for (int neighbor : adj[node]) {
            if (!visited[neighbor]) {
                visited[neighbor] = true;
                q.offer(new int[] { neighbor, node });
            }
            // If visited and not the parent, cycle
            // exists
            else if (neighbor != parent) {
                return true;
            }
        }
    }
    return false;
}
static List<Integer>[] constructadj(int V,
                                    int[][] edges)
{

    List<Integer>[] adj = new ArrayList[V];

    for (int i = 0; i < V; i++) {
        adj[i] = new ArrayList<>();
    }
    for (int[] edge : edges) {
        int u = edge[0], v = edge[1];
        adj[u].add(v);
        adj[v].add(u);
    }

    return adj;
}
static boolean isCycle(int V, int[][] edges)
{
    // Create adjacency list
    List<Integer>[] adj = constructadj(V, edges);
    boolean[] visited = new boolean[V];

    for (int i = 0; i < V; i++) {
        if (!visited[i]) {
            if (bfs(i, adj, visited)) {
                return true;
            }
        }
    }
    return false;
}

public static void main(String[] args)
{
    int[][] edges = {
        {0, 1}, {0, 2}, {0, 3}, {1, 2}, {3, 4}
    };
    int V = 5;
    System.out.println(isCycle(V, edges) ? "true"
                                         : "false");
}

}

Python

from collections import deque

def bfs(start, adj, visited): queue = deque([(start, -1)]) visited[start] = True

while queue:
    node, parent = queue.popleft()

    for neighbor in adj[node]:
        if not visited[neighbor]:
            visited[neighbor] = True
            queue.append((neighbor, node))
        elif neighbor != parent:
            return True
return False

def constructadj(V, edges): adj = [[] for _ in range(V)] # Initialize adjacency list

for edge in edges:
    u, v = edge
    adj[u].append(v)
    adj[v].append(u)

return adj

def iscycle(V, edges): adj = constructadj(V,edges)

visited = [False] * V

for i in range(V):
    if not visited[i]:
        if bfs(i, adj, visited):
            return True

return False

Test the function

edges = [[0, 1], [0, 2], [0, 3], [1, 2], [3, 4]] V = 5 print("true" if iscycle(V, edges) else "false")

C#

using System; using System.Collections.Generic;

class CycleDetection { // Function to perform BFS from a start node static bool Bfs(int start, List[] adj, bool[] visited) { Queue<(int, int)> q = new Queue<(int, int)>(); q.Enqueue((start, -1)); visited[start] = true;

    while (q.Count > 0)
    {
        var (node, parent) = q.Dequeue();

        foreach (int neighbor in adj[node])
        {
            if (!visited[neighbor])
            {
                visited[neighbor] = true;
                q.Enqueue((neighbor, node));
            }
            // If visited and not the parent, cycle exists
            else if (neighbor != parent)
            {
                return true;
            }
        }
    }
    return false;
}

// Function to construct the adjacency list
static List<int>[] constructadj(int V, int[][] edges)
{
    List<int>[] adj = new List<int>[V];

    // Initialize each list in the adjacency list
    for (int i = 0; i < V; i++)
    {
        adj[i] = new List<int>();
    }

    foreach (var edge in edges)
    {
        adj[edge[0]].Add(edge[1]);
        adj[edge[1]].Add(edge[0]);
    }

    return adj;
}

static bool IsCycle(int V, int[][] edges)
{
    // Create adjacency list
    List<int>[] adj = constructadj(V, edges);

    bool[] visited = new bool[V];

    for (int i = 0; i < V; i++)
    {
        if (!visited[i])
        {
            if (Bfs(i, adj, visited))
            {
                return true;
            }
        }
    }
    return false;
}

static void Main()
{
    int[][] edges = new int[][]
    {
        new int[] {0, 1}, new int[] {0, 2}, new int[] {0, 3}, 
        new int[] {1, 2}, new int[] {3, 4}
    };
    int V = 5;
    Console.WriteLine(IsCycle(V, edges) ? "true" : "false");
}

}

JavaScript

function bfs(start, adj, visited) { let queue = [[start, -1]]; visited[start] = true;

while (queue.length > 0) {
    let [node, parent] = queue.shift();

    for (let neighbor of adj[node]) {
        if (!visited[neighbor]) {
            visited[neighbor] = true;
            queue.push([neighbor, node]);
        } else if (neighbor !== parent) {
            return true;
        }
    }
}
return false;

}

function constructadj(V, edges){ let adj = Array.from({length : V}, () => []);

// Build the adjacency list
for (let edge of edges) {
    let [u, v] = edge;
    adj[u].push(v);
    adj[v].push(u);
}
return adj;

}

function isCycle(V, edges) { let adj = constructadj(V,edges);

let visited = Array(V).fill(false);

for (let i = 0; i < V; i++) {
    if (!visited[i]) {
        if (bfs(i, adj, visited)) {
            return true;
        }
    }
}

return false;

}

// Test the function let edges = [[0, 1], [0, 2], [0, 3], [1, 2], [3, 4]]; let V = 5; console.log(isCycle(V, edges) ? "true" : "false");

`

**Time Complexity: **O(V+E), It visits each node once and processes each edge once using an adjacency list.
**Space Complexity: O(V), O(V) for the queue and visited array.

We do not count the adjacency list in auxiliary space as it is necessary for representing the input graph.

**Related Articles: