Last Updated: 25 Mar, 2021

Redundant Connection - I

Moderate
Asked in companies
AdobeIBM

Problem statement

You are given a graph that started as a tree with ‘N’ nodes (with distinct values 1, 2, ..., N), with one additional edge added. The added edge has two different vertices chosen from 1 to N and was not an edge that already existed. The resulting graph is given as a 2D-array of edges ARR of size NX2. Each element of edges is a pair [u, v] with u < v, which represents an undirected edge connecting nodes u and v.

For the given graph you are required to find an edge that can be removed such that the graph becomes a tree of N nodes.

Example:

 Let’s say we have 3 edges that are {1 , 2} , {1 , 3} and {2 , 3}. So 
 the resulting graph from these edges will be :
      1
     / \
    2 - 3

If we remove the edge {2, 3} then the resulting graph will be a tree with N nodes.
Input format:
The very first line of input contains an integer ‘T’ denoting the number of test cases. 

The first line of every test case contains an integer ‘N’ denoting the number of nodes of the graph.

The second line of every test case contains a 2d array 'ARR' of NX2 size, which contains N edges of the graph.
Output format:
For each test case, return that single edge that if removed, the resulting graph will be a tree of N nodes.


Output for each test case is printed on a separate line.
Note:
You do not need to print anything, it has already been taken care of. Just return an edge that can be removed so that the resulting graph is a tree of N nodes.

If there are multiple answers, return the answer that occurs last in the given 2D array ARR of size NX2. The answer edge [u, v] should be in the same format, with u < v.
Constraints:
1 <= T <= 10
3 <= N <= 10^3
1 <= ARR[i] <= N

Time Limit: 1 sec

Approaches

01 Approach

Approach:

 

  • This is basically the brute force approach.
  • The idea is to use one edge less from the end each time and to check whether it can make the graph to break into two connected components.
  • Also for ease, we can store the edges in zero-based indexing.

 

Algorithm:

 

  • Take an integer variable ‘N’  equal to the size of the edges array ‘ARR’.
  • Also, store the value of ‘N’ into ‘M’
  • Now till N not equal to 1 do the following steps:
    • Create an Adjacency list ‘ADJ’.
    • Iterate over the edges array ‘ARR’ from i=0 to i=M and each time take one edge less from the end that is if i == N-1 do not push that edge in the Adjacency list otherwise push all the edges in the adjacency list.
    • Now decrement N by one.
    • Now call the depth-first search on the Adjacency list ‘ADJ’ to count the number of connected components.
    • If connected components = 1 then return the edge {ARR[N][0] , ARR[N][1]};
  • If no edge is returned from the above operations return {0, 0} i.e empty vector.

02 Approach

Approach:

 

  • A disjoint-set data structure is a data structure that keeps track of a set of elements partitioned into a number of disjoint (non-overlapping) subsets. A union-find algorithm is an algorithm that performs two useful operations on such a 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.
  • In this approach, we will discuss the application of the Disjoint Set Data Structure. The application is to check whether a given graph contains a cycle or not.
  • Union-Find Algorithm can be used to check whether an undirected graph contains a cycle or not.
  • In this approach, a parent array is taken and this array is updated whenever an edge is encountered.
  • The idea is to traverse over the given edges and for every edge encountered we will update the parent array and side by side also check whether they have the same parent or not using the ‘find operation’. If they have the same parent then we can remove that edge and this edge will be our required answer otherwise we will perform ‘union operation’ on these two edges.
  • You can also refer to this doc https://cp-algorithms.com/data_structures/disjoint_set_union.html for more information.

 

Algorithm:

 

  • First, create a struct is to perform disjoint-set union operations. In the struct define the find operation and union operation.
  • Traverse over the given array of edges ‘ARR’ and for every edge do the following:
    • Find the source and the target from each edge.
    • Check for overlapping connections through union function of DSU structure.
    • So if the union function returns false then return that edge as the answer because the nodes of that edge have the same parent.
  • If the above operations do not return the edge then return an empty vector.