Software Development

Verify if including an edge makes the Undirected Graph cyclic or not

Verify if including an edge makes the Undirected Graph cyclic or not
Written by admin


Enhance Article

Save Article

Like Article

Enhance Article

Save Article

Given an undirected graph, the duty is to if including an edge makes the graph cyclic or not.

In an Undirected graph, a cycle is a path of edges that connects a sequence of vertices again to itself. In different phrases, a cycle is a closed loop of edges that permits you to traverse the graph and return to the beginning vertex.

For instance:

    A — B
  /          
C            D
           /
   E — F

On this graph, there are a number of cycles that may be fashioned by following totally different sequences of edges. For instance, the sequence of edges A-B-D-F-E-C-A varieties a cycle, as does the sequence    B-D-F-E-C-A-B.

Naive method: The essential technique to clear up the issue is as follows:

Use depth-first Search to detect the cycle in the course of the insertion of the nodes. If whereas traversing we attain a node that’s already visited. This means that cycle is fashioned. 

Observe the steps beneath to resolve the issue:

  • Create a detect cycle operate that takes a graph and a brand new node as enter.
  • Outline a dfs operate that takes a graph, a node, a set of visited nodes, and a search path array as enter.
  • Within the detectCycle operate, initialize an empty set of visited nodes and an empty search path array.
  • Name the dfs operate, ranging from the brand new node, and passing the graph, visited nodes, and search path array as arguments.
  • Return the results of the dfs operate.
  • Within the dfs operate, mark the present node as visited and add it to the search path array.
  • Verify all of the neighbors of the present node.
  • For every neighbor:
    • If the neighbor is already visited, verify whether it is within the present search path.
    • Whether it is, then we have now discovered a cycle, so return true.
    • If it isn’t visited, proceed the DFS from that node. If the DFS returns true, then return true as nicely.
  • Take away the present node from the search path array.
  • Return false.

Beneath is the implementation of the above method:

Java

// Java implementation of the above method
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Checklist;
import java.util.Map;
import java.util.Set;

public class GraphCycleDetector {

      // Operate to detect cycle is fashioned 
      // by including an edge
    public static boolean
    detectCycle(Map<Integer, Checklist<Integer> > graph,
                int newNode)
    {
      
        // Carry out a DFS ranging from the 
          // new node
        Set<Integer> visited = new HashSet<>();
        Checklist<Integer> path = new ArrayList<>();
        boolean cycleExists
            = dfs(graph, newNode, visited, path);
        
          // Return true, if cycle fashioned
        return cycleExists;
      
    }
    
  
      // Operate to traversing over the graph
    non-public static boolean
    dfs(Map<Integer, Checklist<Integer> > graph, int node,
        Set<Integer> visited, Checklist<Integer> path)
    {
      
        // Mark the present node as visited
        visited.add(node);
        path.add(node);

        // Verify if the node has any neighbors
        if (graph.containsKey(node)) {
          
            // Get the record of neighbors
            Checklist<Integer> neighbors = graph.get(node);

            // Verify all of the neighbors of the 
              // present node
            for (int neighbor : neighbors) {
              
                if (visited.comprises(neighbor)) {
                  
                    // If the neighbor is already
                    // visited, verify whether it is 
                    // within the present search path
                    if (path.comprises(neighbor)) {
                      
                        // Whether it is, then we have now 
                        // discovered a cycle
                        return true;
                    }
                }
                else {
                    // If the neighbor shouldn't be 
                    // visited, proceed the DFS 
                      // from that node
                    if (dfs(graph, neighbor, visited,
                            path)) {
                        return true;
                    }
                }
            }
        }

        // Take away the present node from 
          // the search path
        path.take away(path.measurement() - 1);

        return false;
    }
    
      // Driver code
    public static void major(String[] args)
    {
        // Check the detectCycle operate
        Map<Integer, Checklist<Integer> > graph
            = new HashMap<>();
        graph.put(1, Arrays.asList(2, 3));
        graph.put(2, Arrays.asList(1, 3));
        graph.put(3, Arrays.asList(1, 2));
    
          // Operate name
        System.out.println(
            detectCycle(graph, 4)); 

        // Add a brand new node to the graph 
          // that creates a cycle
        graph.put(4, Arrays.asList(1));

        System.out.println(
            detectCycle(graph, 4));
    }
}

Javascript

operate detectCycle(graph, newNode) {
  // Carry out a DFS ranging from the brand new node
  let visited = new Set()
  let path = []
  let cycleExists = dfs(graph, newNode, visited, path)

  return cycleExists
}

operate dfs(graph, node, visited, path) {
  // Mark the present node as visited
  visited.add(node)
  path.push(node)

  // Verify if the node has any neighbors
  if (graph[node]) {
    // Convert the neighbors to an array if obligatory
    let neighbors = Array.isArray(graph[node]) ? graph[node] : [graph[node]]

    // Verify all of the neighbors of the present node
    for (let neighbor of neighbors) {
      if (visited.has(neighbor)) {
        // If the neighbor is already visited, verify whether it is within the present search path
        if (path.contains(neighbor)) {
          // Whether it is, then we have now discovered a cycle
          return true
        }
      } else {
        // If the neighbor shouldn't be visited, proceed the DFS from that node
        if (dfs(graph, neighbor, visited, path)) {
          return true
        }
      }
    }
  }

  // Take away the present node from the search path
  path.pop()

  return false
}
// Check the detectCycle operate
let graph = {
  1: [2, 3],
  2: [1, 3],
  3: [1, 2],
}

console.log(detectCycle(graph, 4)) // ought to print false

// Add a brand new node to the graph that creates a cycle
graph[4] = [1]

console.log(detectCycle(graph, 4)) // ought to print true

Time complexity:  O(V+E), the place V is the variety of vertices (or nodes) within the graph, and E is the variety of edges within the graph.
Auxiliary Area:  O(V)

Environment friendly Method: The above method may be optimized based mostly on the next concept:

  • The method used within the above code is a union-find-based method to detect cycles within the graph. 
  • The discover() technique is used to search out the basis of the tree representing a given node, and 
  • the addEdge() technique makes use of the discover() technique to search out the roots of the timber representing the 2 nodes being related by the sting. 
  • If the roots are the identical, it signifies that the 2 nodes are already in the identical related element, and including the sting would create a cycle within the graph. 
  • If the roots are totally different, the addEdge() technique merges the 2 related parts by attaching the basis of the smaller tree to the basis of the bigger tree.

Beneath is the implementation of the above method:

Java

// Java Implementation of the above method
import java.io.*;
import java.util.ArrayList;
import java.util.Checklist;

public class Graph {
    non-public closing int V;
    non-public closing Checklist<Checklist<Integer> > adj;
    non-public closing int[] dad or mum;
    non-public closing int[] rank;

    // Operate to create Graph
    public Graph(int V)
    {

        this.V = V;
        adj = new ArrayList<>(V);
        for (int i = 0; i < V; i++) {
            adj.add(new ArrayList<>());
        }
        dad or mum = new int[V];
        rank = new int[V];
        for (int i = 0; i < V; i++) {
            dad or mum[i] = i;
            rank[i] = 0;
        }
    }

    // Operate so as to add edge in graph
    public boolean addEdge(int u, int v)
    {
        // Discover the roots of the timber
        // representing u and v
        int rootU = discover(u);
        int rootV = discover(v);
        if (rootU == rootV) {
            // If the roots are the identical,
            // then u and v are already within the
            // identical related element, so
            // including the sting (u, v) would create a cycle
            return false;
        }
        // If the roots are totally different, merge
        // the 2 related parts by
        // attaching the basis of the smaller tree
        // to the basis of the bigger tree
        if (rank[rootU] < rank[rootV]) {

            dad or mum[rootU] = rootV;
        }
        else if (rank[rootU] > rank[rootV]) {
            dad or mum[rootV] = rootU;
        }
        else {
            dad or mum[rootV] = rootU;
            rank[rootU]++;
        }
        // Add the sting (u, v) to the adjacency
        // record
        adj.get(u).add(v);
        adj.get(v).add(u);
        return true;
    }

    non-public int discover(int u)
    {
        // Discover the basis of the tree
        // representing u
        if (dad or mum[u] != u) {

            dad or mum[u] = discover(dad or mum[u]);
        }
        return dad or mum[u];
    }

    // Driver code
    public static void major(String[] args)
    {

        Graph graph = new Graph(4);
        graph.addEdge(0, 1);
        graph.addEdge(0, 2);
        graph.addEdge(1, 2);
        // graph.addEdge(2, 3);

        if (graph.addEdge(2, 3)) {
            // including edge(2,3) wouldn't 
              // create a cycle
            System.out.println("false");
        }
        else {
            // including edge (2, 3) would 
              // create a cycle
            System.out.println("true");
        }

        if (graph.addEdge(3, 0)) {
            // including edge(3,0) wouldn't 
              // create a cycle
            System.out.println("false");
        }
        else {
            // including edge (3, 0) would 
              // create a cycle
            System.out.println("true");
        }
    }
}

Time complexity: O(E log V)
Auxiliary Area: O(V)

About the author

admin

Leave a Comment