Skip to content
Related Articles

Related Articles

Improve Article

Construct a Graph from size of components for each node

  • Difficulty Level : Hard
  • Last Updated : 13 Aug, 2021
Geek Week

Given an array A[] of size N, for each index i in the range [0, N) the value A[i] denotes the size of the connected component of node i. The task is to find the edges for the possible graph else print -1.

Note: There may be more than 1 possible answers for each array. Print any one of them. 

Examples:

Input: N = 5, A[] = {2, 1, 1, 2, 1}
Output: {{0, 3}}
Explanation: The size of Connected Components of nodes (0, 3) is 2, every other node is singular.

Input: N = 4, A[] = {2, 2, 2, 2}
Output: {{0, 1}, {2, 3}}
Explanation: Other possible variations are – {{0, 2}, {1, 3}}, {{0, 3}, {1, 2}}



Input: N=2, A[] = {1, 1}
Output: Graph is already connected.
Explanation: Since, each connected component size is 1, no edge is needed to connect any pair of nodes.

Approach: The idea is to observe that all the same component sizes can be connected with each other using total nodes equal to the size of the array value. So, store all the nodes with the same index value into a map. The values of nodes can be stored with a map structure map<int, vector<int>>. Check for each size of connected component that the corresponding total nodes are a multiple of the size. If for any connected component the above condition fails then there will be no valid graph. Return -1 immediately. Otherwise for all multiple stores the vertices and connect them adjacently. Store all edges in an array and output the result. Follow the steps below to solve the problem:

  • Initialize a boolean variable flag as false to check if all the values are 1. If so, then there is no need to form any edge.
  • Initialize a map of vector mp[] to store the indices for a particular connected component size.
  • Iterate over the range [0, N) using the variable i and perform the following tasks:
  • If flag is false, then return.
  • Iterate over the map using the variable x and perform the following tasks:
    • If x.second.size() is not divisible by x.first, then print -1 and return 0.
  • Initialize a vector of pair of int edges[] to store the edges.
  • Iterate over the map using the variable x and perform the following tasks:
  • After performing the above steps, print the vector edges[] as the answer.

Below is the implementation of the above approach:

C++




// C++ Program for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to construct the graph for
// the given array
int constructConnectedComponent(int A[], int N)
{
  
    // Variable to check if all the values
    // are 1, then no need to form any edge
    bool flag = false;
  
    // Iterate through the array and store
    // the indices in a
    // map of same size connected component
    map<int, vector<int> > mp;
    for (int i = 0; i < N; i++) {
        mp[A[i]].push_back(i);
        if (A[i] != 1)
            flag = true;
    }
  
    if (!flag) {
        cout << "Graph already connected.\n";
        return 0;
    }
  
    // Check if the total size of vector is a
    // multiple of size
    for (auto x : mp) {
        if ((x.second).size() % x.first != 0) {
            cout << -1;
            return 0;
        }
    }
  
    // Make a vector to store the edges
    vector<pair<int, int> > edges;
  
    // Start constructing edges with each multiple
    // from the corresponding vector
    for (auto x : mp) {
        vector<int> nodes = x.second;
        while (!nodes.empty()) {
            int cnt = 0;
            vector<int> component_nodes;
            while (cnt != x.first) {
                component_nodes.push_back(nodes.back());
                nodes.pop_back();
                cnt++;
            }
  
            // Make edges between selected node
            for (int i = 1; i < component_nodes.size();
                 i++) {
                edges.push_back(
                    make_pair(component_nodes[i],
                              component_nodes[i - 1]));
            }
        }
    }
  
    // Print the edges of the graph
    cout << "[";
    for (int i = 0; i < edges.size(); i++) {
        cout << "{" << edges[i].first << ", "
             << edges[i].second << "}";
        if (i != edges.size() - 1) {
            cout << ", ";
        }
    }
    cout << "]";
  
    return 0;
}
  
// Driver Code
int main()
{
    int N = 5;
    int A[] = { 2, 1, 1, 2, 1 };
  
    constructConnectedComponent(A, N);
  
    return 0;
}
Output:
[{0, 3}]

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :