Skip to content
Related Articles

Related Articles

Maximum GCD of all nodes in a connected component of an Undirected Graph
  • Difficulty Level : Expert
  • Last Updated : 16 Mar, 2021

Given an undirected graph consisting of V vertices and a 2d array E[][2] denoting edges between pairs of nodes. Given another array arr[] representing values assigned to each node, the task is to find the maximum GCD among the GCD of all connected components in the graph.

Examples:

Input: V = 5, E[][2] = {{1, 3}, {2, 3}, {1, 2}}, arr[] = {23, 43, 123, 54, 2}
Output: 54
Explanation: 
 

Connected component {1, 2, 3}: GCD(arr[1], arr[2], arr[3]) = GCD(23, 43, 123) = 1.
Connected component {4}: GCD = 54.
Connected component {5}: GCD = 2.
Therefore, the maximum GCD is 54.



Input: V = 5, E = {{1, 2}, {1, 3}, {4, 5}}, arr[] = { 10, 10, 10, 15, 15 }
Output: 15

Approach: The given problem can be solved by performing Depth First Search traversal on the given graph and then find the maximum GCD among all the connected components. Follow the steps below to solve the problem:

  • Initialize a variable, say maxGCD as INT_MIN, to store the maximum GCD among all the connected components.
  • Initialize another variable, say currentGCD as 0, to store the GCD of each connected component independently.
  • Initialize an auxiliary array visited[] as false to store the visited nodes in the DFS Traversal.
  • Iterate over each vertex over the range [1, V] and perform the following steps:
    • If the current vertex is not visited, i.e. visited[i] = false, then initialize currentGCD as 0.
    • Perform DFS Traversal from the current vertex with the currentGCD value and update currentGCD value as the GCD of currentGCD and arr[i – 1] in each recursive call.
    • If the value of currentGCD is greater than maxGCD, then update maxGCD as currentGCD.
  • After completing the above steps, print the value of maxGCD as the result.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the  GCD of two
// numbers a and b
int gcd(int a, int b)
{
    // Base Case
    if (b == 0)
        return a;
 
    // Recursively find the GCD
    return gcd(b, a % b);
}
 
// Function to perform DFS Traversal
void depthFirst(int v, vector<int> graph[],
                vector<bool>& visited,
                int& currGCD,
                vector<int> values)
{
    // Mark the visited vertex as true
    visited[v] = true;
 
    // Update GCD of current
    // connected component
    currGCD = gcd(currGCD, values[v - 1]);
 
    // Traverse all adjacent nodes
    for (auto child : graph[v]) {
 
        if (visited[child] == false) {
 
            // Recursive call to perform
            // DFS traversal
            depthFirst(child, graph, visited,
                       currGCD, values);
        }
    }
}
 
// Function to find the maximum GCD
// of nodes among all the connected
// components of an undirected graph
void maximumGcd(int Edges[][2], int E,
                int V, vector<int>& arr)
{
    vector<int> graph[V + 1];
 
    // Traverse the edges
    for (int i = 0; i < E; i++) {
 
        int u = Edges[i][0];
        int v = Edges[i][1];
 
        graph[u].push_back(v);
        graph[v].push_back(u);
    }
 
    // Initialize boolean array
    // to mark visited vertices
    vector<bool> visited(V + 1, false);
 
    // Stores the maximum GCD value
    int maxGCD = INT_MIN;
 
    // Traverse all the vertices
    for (int i = 1; i <= V; i++) {
 
        // If node is not visited
        if (visited[i] == false) {
 
            // Stores GCD of current
            // connected component
            int currGCD = 0;
 
            // Perform DFS Traversal
            depthFirst(i, graph, visited,
                       currGCD, arr);
 
            // Update maxGCD
            if (currGCD > maxGCD) {
                maxGCD = currGCD;
            }
        }
    }
 
    // Print the result
    cout << maxGCD;
}
 
// Driver Code
int main()
{
    int E = 3, V = 5;
    vector<int> arr = { 23, 43, 123, 54, 2 };
    int Edges[][2] = { { 1, 3 }, { 2, 3 }, { 1, 2 } };
 
    maximumGcd(Edges, E, V, arr);
 
    return 0;
}

Java




// Java program for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
  static int currGCD;
 
  // Function to find the  GCD of two
  // numbers a and b
  static int gcd(int a, int b)
  {
    // Base Case
    if (b == 0)
      return a;
 
    // Recursively find the GCD
    return gcd(b, a % b);
  }
 
  // Function to perform DFS Traversal
  static void depthFirst(int v,
                         ArrayList<Integer> graph[],
                         boolean visited[], int values[])
  {
    // Mark the visited vertex as true
    visited[v] = true;
 
    // Update GCD of current
    // connected component
    currGCD = gcd(currGCD, values[v - 1]);
 
    // Traverse all adjacent nodes
    for (int child : graph[v]) {
 
      if (visited[child] == false) {
 
        // Recursive call to perform
        // DFS traversal
        depthFirst(child, graph, visited, values);
      }
    }
  }
 
  // Function to find the maximum GCD
  // of nodes among all the connected
  // components of an undirected graph
  static void maximumGcd(int Edges[][], int E, int V,
                         int arr[])
  {
 
    ArrayList<Integer> graph[] = new ArrayList[V + 1];
 
    // Initialize the graph
    for (int i = 0; i < V + 1; i++)
      graph[i] = new ArrayList<>();
 
    // Traverse the edges
    for (int i = 0; i < E; i++) {
 
      int u = Edges[i][0];
      int v = Edges[i][1];
 
      graph[u].add(v);
      graph[v].add(u);
    }
 
    // Initialize boolean array
    // to mark visited vertices
    boolean visited[] = new boolean[V + 1];
 
    // Stores the maximum GCD value
    int maxGCD = Integer.MIN_VALUE;
 
    // Traverse all the vertices
    for (int i = 1; i <= V; i++) {
 
      // If node is not visited
      if (visited[i] == false) {
 
        // Stores GCD of current
        // connected component
        currGCD = 0;
 
        // Perform DFS Traversal
        depthFirst(i, graph, visited, arr);
 
        // Update maxGCD
        if (currGCD > maxGCD) {
          maxGCD = currGCD;
        }
      }
    }
 
    // Print the result
    System.out.println(maxGCD);
  }
   
  // Driver Code
  public static void main(String[] args)
  {
 
    int E = 3, V = 5;
    int arr[] = { 23, 43, 123, 54, 2 };
    int Edges[][] = { { 1, 3 }, { 2, 3 }, { 1, 2 } };
 
    maximumGcd(Edges, E, V, arr);
  }
}
 
// Thi code is contributed by Kingash.

Python3




# Python 3 program for the above approach
from math import gcd
import sys
 
# Function to find the  GCD of two
# numbers a and b
currGCD = 0
 
# Function to perform DFS Traversal
def depthFirst(v, graph, visited, values):
    global currGCD
     
    # Mark the visited vertex as true
    visited[v] = True
 
    # Update GCD of current
    # connected component
    currGCD = gcd(currGCD, values[v - 1])
 
    # Traverse all adjacent nodes
    for child in graph[v]:
        if (visited[child] == False):
           
            # Recursive call to perform
            # DFS traversal
            depthFirst(child, graph, visited, values)
 
# Function to find the maximum GCD
# of nodes among all the connected
# components of an undirected graph
def maximumGcd(Edges, E, V, arr):
    global currGCD
    graph = [[] for i in range(V + 1)]
 
    # Traverse the edges
    for i in range(E):
        u = Edges[i][0]
        v = Edges[i][1]
 
        graph[u].append(v)
        graph[v].append(u)
 
    # Initialize boolean array
    # to mark visited vertices
    visited = [False for i in range(V+1)]
 
    # Stores the maximum GCD value
    maxGCD = -sys.maxsize - 1
 
    # Traverse all the vertices
    for i in range(1, V + 1, 1):
       
        # If node is not visited
        if (visited[i] == False):
           
            # Stores GCD of current
            # connected component
            currGCD = 0
 
            # Perform DFS Traversal
            depthFirst(i, graph, visited, arr)
 
            # Update maxGCD
            if (currGCD > maxGCD):
                maxGCD = currGCD
 
    # Print the result
    print(maxGCD)
 
# Driver Code
if __name__ == '__main__':
    E = 3
    V = 5
    arr =  [23, 43, 123, 54, 2]
    Edges =  [[1, 3 ], [2, 3], [1, 2]]
    maximumGcd(Edges, E, V, arr)
 
    # This code is contributed by ipg2016107.
Output: 
54

 

Time Complexity: O((V + E) * log(M)), where M is the smallest element of the given array arr[].
Auxiliary Space: O(V)

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.

My Personal Notes arrow_drop_up
Recommended Articles
Page :