Open In App

Find the size of the Largest connected GCD Component

Last Updated : 28 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr of size N. Consider a graph formed using the given array where the graph has N vertices and the value of i’th vertices is arr[i] there is an edge between i’th and j’th vertice if gcd(arr[i], arr[j])>1. Your task is to print the size of the largest connected component formed with the above graph.

Examples:

Input: N=6, arr[]={10, 4, 2, 5, 3, 9}
Output: 4
Explanation: there are two components of 4, 2, largest is 4.

Input: N=10, arr[]={2, 10, 10, 1, 13, 8, 20, 2, 2, 16}
Output: 8
Explanation: there are eight components and the largest is 8.

Largest GCD Component using DSU:

  • Find the prime factors of every value.
  • Initialise n sets, each containing one vertex.
  • For every prime factor, we find if there is a set containing this prime factor. For this, we will make an array of ‘PRIMEFACTORS’.
  • If there is no set containing ‘K’ as a prime factor, then ‘PRIMEFACTORS[K]’ is equal to -1.
  • Else, ‘PRIMEFACTORS[K]’ is equal to the set number that contains ‘K’ as a prime factor.
  • Iterate on the vertices, let ‘x’ denote the current vertex.
  • Iterate on the prime factors of ‘x’, let ‘K’ denote the current prime factor.
  • If ‘PROMEFACTORS[K]’ is not equal to -1, then combine the set containing vertex ‘x’ and the set containing ‘K’ as a prime factor.
  • Return the maximum size

Below is the C++ implementation of the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
// Function to find the representative of the
// set containing the given element.
int findSet(int element, vector<int>& parentNodes)
{
    if (element == parentNodes[element]) {
        return element;
    }
    parentNodes[element]
        = findSet(parentNodes[element], parentNodes);
    return parentNodes[element];
}
 
// Function to create a new set with
// the given element.
void establishSet(int element, vector<int>& parentNodes,
                vector<int>& componentSizes)
{
    parentNodes[element] = element;
    componentSizes[element] = 1;
}
 
// Function to unify (merge) two sets to
// which 'a' and 'b' belong.
void unifySets(int a, int b, vector<int>& parentNodes,
            vector<int>& componentSizes)
{
    a = findSet(a, parentNodes);
    b = findSet(b, parentNodes);
 
    if (a != b) {
 
        if (componentSizes[a] < componentSizes[b]) {
            swap(a, b);
        }
 
        parentNodes[b] = a;
        componentSizes[a] += componentSizes[b];
    }
}
 
// Function to extract the prime factors
// of a given value.
vector<int> extractPrimeFactors(int value)
{
    vector<int> primeFactors;
 
    for (int i = 2; i * i <= value; i++) {
        if (value % i == 0) {
            while (value % i == 0) {
                value /= i;
            }
            primeFactors.push_back(i);
        }
    }
 
    if (value > 1) {
        primeFactors.push_back(value);
    }
 
    return primeFactors;
}
 
// Function to find the size of the largest
// connected component in an array.
int largestConnectedComponentSize(vector<int>& array, int n)
{
 
    vector<int> parentNodes(n), componentSizes(n);
 
    // Initialize each element as a separate set.
    for (int i = 0; i < n; i++) {
        establishSet(i, parentNodes, componentSizes);
    }
 
    // Calculate prime factors for each
    // element in the array.
    vector<int> primeFactorsArray[n];
    for (int i = 0; i < n; i++) {
        primeFactorsArray[i]
            = extractPrimeFactors(array[i]);
    }
 
    int maximumElement = 0;
    // Find the maximum element in the array.
    for (int i = 0; i < n; i++) {
        maximumElement = max(maximumElement, array[i]);
    }
 
    vector<int> isPresent(maximumElement + 1, -1);
    // Union elements based on common
    // prime factors.
    for (int i = 0; i < n; i++) {
 
        for (int j = 0; j < primeFactorsArray[i].size();
            j++) {
            int x = primeFactorsArray[i][j];
 
            if (isPresent[x] != -1) {
                unifySets(isPresent[x], i, parentNodes,
                        componentSizes);
            }
            isPresent[x] = i;
        }
    }
 
    int largestComponentSize = 0;
    // Find the size of the largest
    // connected component.
    for (int i = 0; i < n; i++) {
        largestComponentSize
            = max(largestComponentSize, componentSizes[i]);
    }
 
    return largestComponentSize;
}
 
// Driver Code
int main()
{
    int N = 6;
    vector<int> arr = { 10, 4, 2, 5, 3, 9 };
 
    // Calculate and display the size of
    // the largest connected component.
    int largestComponentSize
        = largestConnectedComponentSize(arr, N);
    cout << largestComponentSize << endl;
 
    return 0;
}


Java




import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
public class LargestConnectedComponent {
 
    // Function to find the representative of the
    // set containing the given element.
    static int findSet(int element, int[] parentNodes) {
        if (element == parentNodes[element]) {
            return element;
        }
        parentNodes[element] = findSet(parentNodes[element], parentNodes);
        return parentNodes[element];
    }
 
    // Function to create a new set with
    // the given element.
    static void establishSet(int element, int[] parentNodes, int[] componentSizes) {
        parentNodes[element] = element;
        componentSizes[element] = 1;
    }
 
    // Function to unify (merge) two sets to
    // which 'a' and 'b' belong.
    static void unifySets(int a, int b, int[] parentNodes, int[] componentSizes) {
        a = findSet(a, parentNodes);
        b = findSet(b, parentNodes);
 
        if (a != b) {
            if (componentSizes[a] < componentSizes[b]) {
                int temp = a;
                a = b;
                b = temp;
            }
 
            parentNodes[b] = a;
            componentSizes[a] += componentSizes[b];
        }
    }
 
    // Function to extract the prime factors
    // of a given value.
    static List<Integer> extractPrimeFactors(int value) {
        List<Integer> primeFactors = new ArrayList<>();
 
        for (int i = 2; i * i <= value; i++) {
            if (value % i == 0) {
                while (value % i == 0) {
                    value /= i;
                }
                primeFactors.add(i);
            }
        }
 
        if (value > 1) {
            primeFactors.add(value);
        }
 
        return primeFactors;
    }
 
    // Function to find the size of the largest
    // connected component in an array.
    static int largestConnectedComponentSize(int[] array, int n) {
        int[] parentNodes = new int[n];
        int[] componentSizes = new int[n];
 
        // Initialize each element as a separate set.
        for (int i = 0; i < n; i++) {
            establishSet(i, parentNodes, componentSizes);
        }
 
        // Calculate prime factors for each
        // element in the array.
        List<Integer>[] primeFactorsArray = new ArrayList[n];
        for (int i = 0; i < n; i++) {
            primeFactorsArray[i] = extractPrimeFactors(array[i]);
        }
 
        int maximumElement = Arrays.stream(array).max().orElse(0);
        int[] isPresent = new int[maximumElement + 1];
        Arrays.fill(isPresent, -1);
 
        // Union elements based on common
        // prime factors.
        for (int i = 0; i < n; i++) {
            for (int x : primeFactorsArray[i]) {
                if (isPresent[x] != -1) {
                    unifySets(isPresent[x], i, parentNodes, componentSizes);
                }
                isPresent[x] = i;
            }
        }
 
        int largestComponentSize = 0;
        // Find the size of the largest
        // connected component.
        for (int i = 0; i < n; i++) {
            largestComponentSize = Math.max(largestComponentSize, componentSizes[i]);
        }
 
        return largestComponentSize;
    }
 
    // Driver Code
    public static void main(String[] args) {
        int N = 6;
        int[] arr = {10, 4, 2, 5, 3, 9};
 
        // Calculate and display the size of
        // the largest connected component.
        int largestComponentSize = largestConnectedComponentSize(arr, N);
        System.out.println(largestComponentSize);
    }
}
 
// This code is contributed by shivamgupta310570


Python3




# Python Implementation:
def findSet(element, parentNodes):
    if element == parentNodes[element]:
        return element
    parentNodes[element] = findSet(parentNodes[element], parentNodes)
    return parentNodes[element]
 
def establishSet(element, parentNodes, componentSizes):
    parentNodes[element] = element
    componentSizes[element] = 1
 
def unifySets(a, b, parentNodes, componentSizes):
    a = findSet(a, parentNodes)
    b = findSet(b, parentNodes)
 
    if a != b:
        if componentSizes[a] < componentSizes[b]:
            a, b = b, a
 
        parentNodes[b] = a
        componentSizes[a] += componentSizes[b]
 
def extractPrimeFactors(value):
    primeFactors = []
 
    for i in range(2, int(value**0.5) + 1):
        if value % i == 0:
            while value % i == 0:
                value //= i
            primeFactors.append(i)
 
    if value > 1:
        primeFactors.append(value)
 
    return primeFactors
 
def largestConnectedComponentSize(array, n):
    parentNodes = [0] * n
    componentSizes = [0] * n
 
    for i in range(n):
        establishSet(i, parentNodes, componentSizes)
 
    primeFactorsArray = []
    for i in range(n):
        primeFactorsArray.append(extractPrimeFactors(array[i]))
 
    maximumElement = max(array)
 
    isPresent = [-1] * (maximumElement + 1)
 
    for i in range(n):
        for j in range(len(primeFactorsArray[i])):
            x = primeFactorsArray[i][j]
 
            if isPresent[x] != -1:
                unifySets(isPresent[x], i, parentNodes, componentSizes)
            isPresent[x] = i
 
    largestComponentSize = max(componentSizes)
 
    return largestComponentSize
 
N = 6
arr = [10, 4, 2, 5, 3, 9]
 
largestComponentSize = largestConnectedComponentSize(arr, N)
print(largestComponentSize)
 
# This code is contributed by Tapesh(tapeshdua420)


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
public class GFG
{
    // Function to find the representative of the
    // set containing the given element.
    static int FindSet(int element, int[] parentNodes)
    {
        if (element == parentNodes[element])
        {
            return element;
        }
        parentNodes[element] = FindSet(parentNodes[element], parentNodes);
        return parentNodes[element];
    }
 
    // Function to create a new set with
    // the given element.
    static void EstablishSet(int element, int[] parentNodes, int[] componentSizes)
    {
        parentNodes[element] = element;
        componentSizes[element] = 1;
    }
 
    // Function to unify (merge) two sets to
    // which 'a' and 'b' belong.
    static void UnifySets(int a, int b, int[] parentNodes, int[] componentSizes)
    {
        a = FindSet(a, parentNodes);
        b = FindSet(b, parentNodes);
 
        if (a != b)
        {
            if (componentSizes[a] < componentSizes[b])
            {
                int temp = a;
                a = b;
                b = temp;
            }
 
            parentNodes[b] = a;
            componentSizes[a] += componentSizes[b];
        }
    }
 
    // Function to extract the prime factors
    // of a given value.
    static List<int> ExtractPrimeFactors(int value)
    {
        List<int> primeFactors = new List<int>();
 
        for (int i = 2; i * i <= value; i++)
        {
            if (value % i == 0)
            {
                while (value % i == 0)
                {
                    value /= i;
                }
                primeFactors.Add(i);
            }
        }
 
        if (value > 1)
        {
            primeFactors.Add(value);
        }
 
        return primeFactors;
    }
 
    // Function to find the size of the largest
    // connected component in an array.
    static int LargestConnectedComponentSize(int[] array, int n)
    {
        int[] parentNodes = new int[n];
        int[] componentSizes = new int[n];
 
        // Initialize each element as a separate set.
        for (int i = 0; i < n; i++)
        {
            EstablishSet(i, parentNodes, componentSizes);
        }
 
        // Calculate prime factors for each
        // element in the array.
        List<int>[] primeFactorsArray = new List<int>[n];
        for (int i = 0; i < n; i++)
        {
            primeFactorsArray[i] = ExtractPrimeFactors(array[i]);
        }
 
        int maximumElement = array.Max();
        int[] isPresent = new int[maximumElement + 1];
        Array.Fill<int>(isPresent, -1);
 
        // Union elements based on common
        // prime factors.
        for (int i = 0; i < n; i++)
        {
            foreach (int x in primeFactorsArray[i])
            {
                if (isPresent[x] != -1)
                {
                    UnifySets(isPresent[x], i, parentNodes, componentSizes);
                }
                isPresent[x] = i;
            }
        }
 
        int largestComponentSize = 0;
        // Find the size of the largest
        // connected component.
        for (int i = 0; i < n; i++)
        {
            largestComponentSize = Math.Max(largestComponentSize, componentSizes[i]);
        }
 
        return largestComponentSize;
    }
 
    // Driver Code
    public static void Main()
    {
        int N = 6;
        int[] arr = { 10, 4, 2, 5, 3, 9 };
 
        // Calculate and display the size of
        // the largest connected component.
        int largestComponentSize = LargestConnectedComponentSize(arr, N);
        Console.WriteLine(largestComponentSize);
    }
}
// This code is contributed by rohit singh


Javascript




// Javascript Implementation
 
function findSet(element, parentNodes) {
  if (element === parentNodes[element]) {
    return element;
  }
  parentNodes[element] = findSet(parentNodes[element], parentNodes);
  return parentNodes[element];
}
 
function establishSet(element, parentNodes, componentSizes) {
  parentNodes[element] = element;
  componentSizes[element] = 1;
}
 
function unifySets(a, b, parentNodes, componentSizes) {
  a = findSet(a, parentNodes);
  b = findSet(b, parentNodes);
 
  if (a !== b) {
    if (componentSizes[a] < componentSizes[b]) {
      [a, b] = [b, a];
    }
 
    parentNodes[b] = a;
    componentSizes[a] += componentSizes[b];
  }
}
 
function extractPrimeFactors(value) {
  const primeFactors = [];
 
  for (let i = 2; i <= Math.sqrt(value); i++) {
    if (value % i === 0) {
      while (value % i === 0) {
        value /= i;
      }
      primeFactors.push(i);
    }
  }
 
  if (value > 1) {
    primeFactors.push(value);
  }
 
  return primeFactors;
}
 
function largestConnectedComponentSize(array, n) {
  const parentNodes = Array(n).fill(0);
  const componentSizes = Array(n).fill(0);
 
  for (let i = 0; i < n; i++) {
    establishSet(i, parentNodes, componentSizes);
  }
 
  const primeFactorsArray = [];
  for (let i = 0; i < n; i++) {
    primeFactorsArray.push(extractPrimeFactors(array[i]));
  }
 
  const maximumElement = Math.max(...array);
 
  const isPresent = Array(maximumElement + 1).fill(-1);
 
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < primeFactorsArray[i].length; j++) {
      const x = primeFactorsArray[i][j];
 
      if (isPresent[x] !== -1) {
        unifySets(isPresent[x], i, parentNodes, componentSizes);
      }
      isPresent[x] = i;
    }
  }
 
  const largestComponentSize = Math.max(...componentSizes);
 
  return largestComponentSize;
}
 
const N = 6;
const arr = [10, 4, 2, 5, 3, 9];
 
const largestComponentSize = largestConnectedComponentSize(arr, N);
console.log(largestComponentSize);
 
// This code is contributed by Sakshi


Output

4







Time Complexity: O(N*sqrt(Arr[i])).
Auxiliary Space: O(N + max(Arr[i])).



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads