Open In App

Find edges removing which does not disconnect the Graph

Last Updated : 08 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given N vertices numbered from 0 to N – 1 and E edges to form an undirected graph. All the edges should be added in the given order. The task is to find the edges removing which do not disconnect the graph. If there are multiple possible edges return the ones which occur later in the sequence.

Examples:

Input: N = 3, E = 3, edges= {{0, 1}, {1, 2}, {0, 2}}

 

Output: 0 2
Explanation:  Removing any one of the edges keep the graph connected.
But (0, 2) comes later in the sequence.

Input: N = 5, E = 7, edges = {{0, 1}, {1, 2}, {2, 3}, {4, 3}, {0, 4}, {4, 1}, {3, 0}}

 

Output: 
0 4
4 1
3 0
Explanation: After removing the edges (0, 4), (4, 1), (3, 0) the graph will still be connected. Hence, these three edges are extra edges. 

 

Approach: This problem can be solved using the concept of disjoint set data structure based on the following idea: 

Keep connecting the edges to each other if they are previously not been connected, if they are already connected then the current edge for sure be an extra edge.

Use disjoint sets to find if the nodes are previously connected or not. If they are connected then connect the edge and union those two sets.

Follow the below steps to solve the problem:

  • Create a parent[] array to store the parent nodes of each node.
  • Create a set of pairs (say ans), to store the answer.
  • Run a loop through the given edges.
    • Check if the vertices of the current edge are already connected or not.
    • If they are connected then store this edge into the ans.
    • Else, connect these two vertices and unite those two disjoint sets (i.e., make their parent same).
  • Return and print ans.

Below is the implementation of the above approach:

C++




// C++ code to implement the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// The required Comparator Function.
int find(int x, vector<int>& parent)
{
    if (x == parent[x]) {
        return x;
    }
    return parent[x]
           = find(parent[x], parent);
}
 
// Function to find extra edges
set<pair<int, int> > extraEdges(int n, int e,
                                vector<vector<int> >& edges)
{
    set<pair<int, int> > ans;
    vector<int> parent(n);
    for (int i = 0; i < n; i++) {
        parent[i] = i;
    }
 
    // Loop through the edges
    for (auto x : edges) {
        int vParent = find(x[0], parent);
        int uParent = find(x[1], parent);
        if (vParent == uParent) {
            pair<int, int> p;
            if (x[0] < x[1]) {
                p = { x[0], x[1] };
            }
            else {
                p = { x[1], x[0] };
            }
            ans.insert(p);
        }
        else {
            parent[vParent] = uParent;
        }
    }
 
    // Return the edges
    return ans;
}
 
// Driver code
int main()
{
    int N = 3, E = 3;
    vector<vector<int> > edges
        = { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 2 } };
    set<pair<int, int> > ans = extraEdges(N,
                                          E, edges);
    for (auto& edge : ans) {
        cout << edge.first << " " << edge.second << "\n";
    }
    return 0;
}


Java




// Java program to implement above approach
import java.util.*;
 
public class GFG {
  static int find(int x, List<Integer> parent)
  {
    if (x == parent.get(x)) {
      return x;
    }
    parent.set(x, find(parent.get(x), parent));
    return parent.get(x);
  }
 
  // Function to find extra edges
  static HashSet<pair>
    extraEdges(int n, int e, List<List<Integer> > edges)
  {
    HashSet<pair> ans = new HashSet<>();
    List<Integer> parent = new ArrayList<>();
    for (int i = 0; i < n; i++) {
      parent.add(i);
    }
 
    // Loop through the edges
    for (List<Integer> x : edges) {
      int vParent = find(x.get(0), parent);
      int uParent = find(x.get(1), parent);
      if (vParent == uParent) {
        pair p = new pair(0, 0);
        if (x.get(0) < x.get(1)) {
          p = new pair(x.get(0), x.get(1));
        }
        else {
          p = new pair(x.get(1), x.get(0));
        }
        ans.add(p);
      }
      else {
        parent.set(vParent, uParent);
      }
    }
 
    // Return the edges
    return ans;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
 
    int N = 3, E = 3;
    List<List<Integer> > edges = new ArrayList<>();
 
    edges.add(new ArrayList<Integer>() {
      {
        add(0);
        add(1);
      }
    });
    edges.add(new ArrayList<Integer>() {
      {
        add(1);
        add(2);
      }
    });
    edges.add(new ArrayList<Integer>() {
      {
        add(2);
        add(0);
      }
    });
    edges.add(new ArrayList<Integer>() {
      {
        add(0);
        add(2);
      }
    });
 
    HashSet<pair> ans = extraEdges(N, E, edges);
    for (pair edge : ans) {
      System.out.println(edge.first + " "
                         + edge.second);
    }
  }
 
  static class pair {
    int first, second;
    pair(int f, int s)
    {
      first = f;
      second = s;
    }
 
    public int hashCode()
    {
      return Objects.hash(first + second);
    }
 
    public boolean equals(Object o)
    {
      if (o == this) {
        return true;
      }
 
      if (!(o instanceof pair)) {
        return false;
      }
 
      pair c = (pair)o;
 
      // Compare the data members and return
      // accordingly
      return (Integer.compare(first, c.first) == 0)
        && (Integer.compare(second, c.second) == 0);
    }
  }
}
 
// This code is contributed by karandeep1234.


C#




// C# program to implement above approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG
{
 
    // The required Comparator Function.
    static int find(int x, List<int> parent)
    {
        if (x == parent[x]) {
            return x;
        }
        return parent[x] = find(parent[x], parent);
    }
 
    // Function to find extra edges
    static SortedSet<pair> extraEdges(int n, int e, List<List<int>> edges)
    {
        SortedSet<pair> ans = new SortedSet<pair>(new Comp());
        List<int> parent = new List<int>();
        for (int i = 0; i < n; i++) {
            parent.Add(i);
        }
 
        // Loop through the edges
        foreach (List<int> x in edges) {
            int vParent = find(x[0], parent);
            int uParent = find(x[1], parent);
            if (vParent == uParent) {
                pair p = new pair(0, 0);
                if (x[0] < x[1]) {
                    p = new pair(x[0], x[1]);
                }
                else {
                    p = new pair(x[1], x[0]);
                }
                ans.Add(p);
            }
            else {
                parent[vParent] = uParent;
            }
        }
 
        // Return the edges
        return ans;
    }
 
    // Driver Code
    public static void Main(string[] args){
         
        int N = 3, E = 3;
        List<List<int>> edges = new List<List<int>>{
            new List<int>{ 0, 1 },
            new List<int>{ 1, 2 },
            new List<int>{ 2, 0 },
            new List<int>{ 0, 2 }
        };
        SortedSet<pair> ans = extraEdges(N,  E, edges);
        foreach (pair edge in ans) {
            Console.WriteLine(edge.first + " " + edge.second);
        }
 
    }
}
 
public class pair{
    public int first;
    public int  second;
    public pair(int first,int second){
        this.first = first;
        this.second = second;
    }
}
 
class Comp : IComparer<pair>{
    public int Compare(pair o2,pair o1){
        if(o1.first == o2.first){
            return o1.second - o2.second;
        }
        return o1.first - o2.first;
    }
}


Python3




# Python3 code to implement the above approach
 
def find(x,parent):
 
    if (x == parent[x]):
        return x
     
    parent[x] = find(parent[x], parent)
    return parent[x]
 
# Function to find extra edges
def extraEdges(n,e,edges):
 
    ans = set()
    parent = [i for i in range(n)]
 
    # Loop through the edges
    for x in edges:
        vParent = find(x[0], parent)
        uParent = find(x[1], parent)
        if (vParent == uParent):
            p = ()
            if (x[0] < x[1]):
                p = ( x[0], x[1] )
             
            else:
                p = ( x[1], x[0] )
         
            ans.add(p)
        else:
            parent[vParent] = uParent
         
 
    # Return the edges
    return ans
 
# Driver code
 
N,E = 3,3
edges = [ [ 0, 1 ], [ 1, 2 ], [ 2, 0 ], [ 0, 2 ] ]
ans = extraEdges(N, E, edges)
for edge in ans:
    print(f"{edge[0]} {edge[1]}")
 
# This code is contributed by shinjanpatra


Javascript




// Function to find the parent of a node
function find(x, parent) {
  if (x === parent[x]) {
    return x;
  }
 
  parent[x] = find(parent[x], parent);
  return parent[x];
}
 
// Function to find extra edges
function extraEdges(n, e, edges) {
  let ans = new Set();
  let parent = [];
  for (let i = 0; i < n; i++) {
    parent[i] = i;
  }
 
  // Loop through the edges
  for (let x of edges) {
    let vParent = find(x[0], parent);
    let uParent = find(x[1], parent);
    if (vParent === uParent) {
      let p = [];
      if (x[0] < x[1]) {
        p = [x[0], x[1]];
      } else {
        p = [x[1], x[0]];
      }
 
      ans.add(p);
    } else {
      parent[vParent] = uParent;
    }
  }
 
  // Return the edges
  return ans;
}
 
// Driver code
let N = 3;
let E = 3;
let edges = [[0, 1], [1, 2], [2, 0], [0, 2]];
let ans = extraEdges(N, E, edges);
for (let edge of ans) {
  console.log(edge[0] + " " + edge[1]);
  break;
}
 
// This code is contributed by lokeshpotta20.


Output

0 2

Time Complexity: O(E * log(N))
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads