Largest component size in a graph formed by connecting non-co-prime nodes
Last Updated :
03 May, 2022
Given a graph with N nodes and their values defined in array A, the task is to find the largest component size in a graph by connecting non-co-prime nodes. An edge is between two nodes U and V if they are non-co-prime, which means that the greatest common divisor of A[U] and A[V] should be greater than 1.
Examples:
Input : A = [4, 6, 15, 35]
Output : 4
Graph will be :
4
|
6
|
15
|
35
Input : A = [2, 3, 6, 7, 4, 12, 21, 39]
Output : 8
Naive Approach:
We can iterate over all the pairs of nodes and check whether they are co-prime or not. If they are not co-prime, we will connect them. Once the graph is created, we will apply Depth First Search to find the maximum component size.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int dfs( int u, vector< int >* adj, int vis[])
{
vis[u] = 1;
int componentSize = 1;
for ( auto it : adj[u]) {
if (!vis[it]) {
componentSize += dfs(it, adj, vis);
}
}
return componentSize;
}
int maximumComponentSize( int a[], int n)
{
vector< int > adj[n];
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++) {
if (__gcd(a[i], a[j]) > 1)
adj[i].push_back(j);
adj[j].push_back(i);
}
}
int answer = 0;
int vis[n];
for ( int k=0;k<n;k++){
vis[k]=0;
}
for ( int i = 0; i < n; i++) {
if (!vis[i]) {
answer = max(answer, dfs(i, adj, vis));
}
}
return answer;
}
int main()
{
int n = 8;
int A[] = { 2, 3, 6, 7, 4, 12, 21, 39 };
cout << maximumComponentSize(A, n);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int dfs( int u, Vector<Integer> []adj,
int vis[])
{
vis[u] = 1 ;
int componentSize = 1 ;
for ( int it : adj[u])
{
if (vis[it] == 0 )
{
componentSize += dfs(it, adj, vis);
}
}
return componentSize;
}
static int maximumComponentSize( int a[], int n)
{
@SuppressWarnings ( "unchecked" )
Vector<Integer> []adj = new Vector[n];
for ( int i = 0 ; i < adj.length; i++)
adj[i] = new Vector<Integer>();
for ( int i = 0 ; i < n; i++)
{
for ( int j = i + 1 ; j < n; j++)
{
if (__gcd(a[i], a[j]) > 1 )
adj[i].add(j);
adj[j].add(i);
}
}
int answer = 0 ;
int []vis = new int [n];
for ( int k = 0 ; k < n; k++)
{
vis[k] = 0 ;
}
for ( int i = 0 ; i < n; i++)
{
if (vis[i] == 0 )
{
answer = Math.max(answer,
dfs(i, adj, vis));
}
}
return answer;
}
static int __gcd( int a, int b)
{
return b == 0 ? a : __gcd(b, a % b);
}
public static void main(String[] args)
{
int n = 8 ;
int A[] = { 2 , 3 , 6 , 7 , 4 , 12 , 21 , 39 };
System.out.print(maximumComponentSize(A, n));
}
}
|
Python3
from math import gcd
def dfs(u, adj, vis):
vis[u] = 1
componentSize = 1
for x in adj[u]:
if (vis[x] = = 0 ):
componentSize + = dfs(x, adj, vis)
return componentSize
def maximumComponentSize(a,n):
adj = [[] for i in range (n)]
for i in range (n):
for j in range (i + 1 , n):
if (gcd(a[i], a[j]) > 1 ):
adj[i].append(j)
adj[j].append(i)
answer = 0
vis = [ 0 for i in range (n)]
for i in range (n):
if (vis[i] = = False ):
answer = max (answer, dfs(i, adj, vis))
return answer
if __name__ = = '__main__' :
n = 8
A = [ 2 , 3 , 6 , 7 , 4 , 12 , 21 , 39 ]
print (maximumComponentSize(A, n))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int dfs( int u,
List< int > []adj,
int []vis)
{
vis[u] = 1;
int componentSize = 1;
foreach ( int it in adj[u])
{
if (vis[it] == 0)
{
componentSize += dfs(it,
adj, vis);
}
}
return componentSize;
}
static int maximumComponentSize( int []a,
int n)
{
List< int > []adj = new List< int >[n];
for ( int i = 0; i < adj.Length; i++)
adj[i] = new List< int >();
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
if (__gcd(a[i], a[j]) > 1)
adj[i].Add(j);
adj[j].Add(i);
}
}
int answer = 0;
int []vis = new int [n];
for ( int k = 0; k < n; k++)
{
vis[k] = 0;
}
for ( int i = 0; i < n; i++)
{
if (vis[i] == 0)
{
answer = Math.Max(answer,
dfs(i,
adj, vis));
}
}
return answer;
}
static int __gcd( int a, int b)
{
return b == 0 ? a :
__gcd(b, a % b);
}
public static void Main(String[] args)
{
int n = 8;
int []A = {2, 3, 6, 7,
4, 12, 21, 39};
Console.Write(maximumComponentSize(A, n));
}
}
|
Javascript
<script>
function dfs(u, adj, vis)
{
vis[u] = 1;
let componentSize = 1;
for (let it in adj[u])
{
if (vis[it] == 0)
{
componentSize += dfs(it,
adj, vis);
}
}
return componentSize;
}
function maximumComponentSize(a, n)
{
let adj = new Array(n);
for ( var i = 0; i < adj.length; i++) {
adj[i] = new Array(2);
}
for ( var i = 0; i < adj.length; i++) {
for ( var j = 0; j < adj.length; j++) {
adj[i][j] = 0;
}
}
for (let i = 0; i < n; i++)
{
for (let j = i + 1; j < n; j++)
{
if (__gcd(a[i], a[j]) > 1)
adj[i].push(j);
adj[j].push(i);
}
}
let answer = 0;
let vis = Array.from({length: n}, (_, i) => 0);
for (let k = 0; k < n; k++)
{
vis[k] = 0;
}
for (let i = 0; i < n; i++)
{
if (vis[i] == 0)
{
answer = Math.max(answer,
dfs(i,
adj, vis));
}
}
return answer;
}
function __gcd(a, b)
{
return b == 0 ? a :
__gcd(b, a % b);
}
let n = 8;
let A = [2, 3, 6, 7, 4, 12, 21, 39];
document.write(maximumComponentSize(A, n));
</script>
|
Output:
8
Time complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach
- For any two numbers to be non-co-prime, they must have at least one common factor. So, instead of traversing through all the pairs, it’s better to prime factorize each node value. The idea is to then club together numbers with common factors as a single group.
- Prime factorization can be done efficiently using the Sieve of Eratosthenes. For clubbing together of nodes we will use a Disjoint set data structure (Union by Rank and Path Compression).
- The following information will be stored :
par[i] -> represents the parent of node i
size[i] -> represents the size of the component node i belongs to
id[p] -> represents which node prime number p was first seen as a factor of A[i]
- For each node value, we will factorize and store the prime factors in set S. Iterate each element of S. If the prime number is seen for the first time as a factor of some number (id[p] is zero), then mark this prime id with the current index. If this prime has been marked, then simply merge this node with that of id[p].
This way, all nodes will belong to some component finally, and size[i] will be the size of component node i belongs to.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int spf[100005];
void sieve()
{
for ( int i = 2; i < 100005; i++) {
if (spf[i] == 0) {
spf[i] = i;
for ( int j = 2 * i; j < 100005; j += i) {
if (spf[j] == 0)
spf[j] = i;
}
}
}
}
void factorize( int n, set< int >& s)
{
while (n > 1) {
int z = spf[n];
s.insert(z);
while (n % z == 0)
n /= z;
}
}
int id[100005];
int par[100005];
int sizeContainer[100005];
int root( int i)
{
if (par[i] == i)
return i;
else
return par[i] = root(par[i]);
}
void merge( int a, int b)
{
int p = root(a);
int q = root(b);
if (p == q)
return ;
if (sizeContainer[p] > sizeContainer[q])
swap(p, q);
par[p] = q;
sizeContainer[q] += sizeContainer[p];
}
int maximumComponentsizeContainer( int a[], int n)
{
for ( int i = 0; i < 100005; i++) {
par[i] = i;
sizeContainer[i] = 1;
}
sieve();
for ( int i = 0; i < n; i++) {
set< int > s;
factorize(a[i], s);
for ( auto it : s) {
if (id[it] == 0)
id[it] = i + 1;
else
merge(i + 1, id[it]);
}
}
int answer = 0;
for ( int i = 0; i < n; i++)
answer = max(answer, sizeContainer[i]);
return answer;
}
int main()
{
int n = 8;
int A[] = { 2, 3, 6, 7, 4, 12, 21, 39 };
cout << maximumComponentsizeContainer(A, n);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int []spf = new int [ 100005 ];
static void sieve()
{
for ( int i = 2 ; i < 100005 ; i++)
{
if (spf[i] == 0 )
{
spf[i] = i;
for ( int j = 2 * i; j < 100005 ; j += i)
{
if (spf[j] == 0 )
spf[j] = i;
}
}
}
}
static void factorize( int n, HashSet<Integer> s)
{
while (n > 1 )
{
int z = spf[n];
s.add(z);
while (n % z == 0 )
n /= z;
}
}
static int []id = new int [ 100005 ];
static int []par = new int [ 100005 ];
static int []sizeContainer = new int [ 100005 ];
static int root( int i)
{
if (par[i] == i)
return i;
else
return par[i] = root(par[i]);
}
static void merge( int a, int b)
{
int p = root(a);
int q = root(b);
if (p == q)
return ;
if (sizeContainer[p] > sizeContainer[q])
{
p = p + q;
q = p - q;
p = p - q;
}
par[p] = q;
sizeContainer[q] += sizeContainer[p];
}
static int maximumComponentsizeContainer( int a[],
int n)
{
for ( int i = 0 ; i < 100005 ; i++)
{
par[i] = i;
sizeContainer[i] = 1 ;
}
sieve();
for ( int i = 0 ; i < n; i++)
{
HashSet<Integer> s = new HashSet<Integer>();
factorize(a[i], s);
for ( int it : s)
{
if (id[it] == 0 )
id[it] = i + 1 ;
else
merge(i + 1 , id[it]);
}
}
int answer = 0 ;
for ( int i = 0 ; i < n; i++)
answer = Math.max(answer, sizeContainer[i]);
return answer;
}
public static void main(String[] args)
{
int n = 8 ;
int A[] = { 2 , 3 , 6 , 7 ,
4 , 12 , 21 , 39 };
System.out.print(
maximumComponentsizeContainer(A, n));
}
}
|
Python3
spf = [ 0 for i in range ( 100005 )]
def sieve():
for i in range ( 2 , 100005 ):
if (spf[i] = = 0 ):
spf[i] = i;
for j in range ( 2 * i, 100005 , i):
if (spf[j] = = 0 ):
spf[j] = i;
def factorize(n, s):
while (n > 1 ):
z = spf[n];
s.add(z);
while (n % z = = 0 ):
n / / = z;
id = [ 0 for i in range ( 100005 )]
par = [ 0 for i in range ( 100005 )]
sizeContainer = [ 0 for i in range ( 100005 )]
def root(i):
if (par[i] = = i):
return i;
else :
return root(par[i]);
return par[i]
def merge(a, b):
p = root(a);
q = root(b);
if (p = = q):
return ;
if (sizeContainer[p] > sizeContainer[q]):
p = p + q;
q = p - q;
p = p - q;
par[p] = q;
sizeContainer[q] + = sizeContainer[p];
def maximumComponentsizeContainer(a, n):
for i in range ( 100005 ):
par[i] = i;
sizeContainer[i] = 1 ;
sieve();
for i in range (n):
s = set ()
factorize(a[i], s);
for it in s:
if ( id [it] = = 0 ):
id [it] = i + 1 ;
else :
merge(i + 1 , id [it]);
answer = 0 ;
for i in range (n):
answer = max (answer, sizeContainer[i]);
return answer;
if __name__ = = '__main__' :
n = 8 ;
A = [ 2 , 3 , 6 , 7 , 4 , 12 , 21 , 39 ]
print (maximumComponentsizeContainer(A, n));
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int []spf = new int [100005];
static void sieve()
{
for ( int i = 2; i < 100005; i++)
{
if (spf[i] == 0)
{
spf[i] = i;
for ( int j = 2 * i; j < 100005; j += i)
{
if (spf[j] == 0)
spf[j] = i;
}
}
}
}
static void factorize( int n, HashSet< int > s)
{
while (n > 1)
{
int z = spf[n];
s.Add(z);
while (n % z == 0)
n /= z;
}
}
static int []id = new int [100005];
static int []par = new int [100005];
static int []sizeContainer = new int [100005];
static int root( int i)
{
if (par[i] == i)
return i;
else
return par[i] = root(par[i]);
}
static void merge( int a, int b)
{
int p = root(a);
int q = root(b);
if (p == q)
return ;
if (sizeContainer[p] > sizeContainer[q])
{
p = p + q;
q = p - q;
p = p - q;
}
par[p] = q;
sizeContainer[q] += sizeContainer[p];
}
static int maximumComponentsizeContainer( int []a,
int n)
{
for ( int i = 0; i < 100005; i++)
{
par[i] = i;
sizeContainer[i] = 1;
}
sieve();
for ( int i = 0; i < n; i++)
{
HashSet< int > s = new HashSet< int >();
factorize(a[i], s);
foreach ( int it in s)
{
if (id[it] == 0)
id[it] = i + 1;
else
merge(i + 1, id[it]);
}
}
int answer = 0;
for ( int i = 0; i < n; i++)
answer = Math.Max(answer, sizeContainer[i]);
return answer;
}
public static void Main(String[] args)
{
int n = 8;
int []A = { 2, 3, 6, 7,
4, 12, 21, 39 };
Console.Write(
maximumComponentsizeContainer(A, n));
}
}
|
Javascript
<script>
var spf = Array(100005).fill(0);
function sieve()
{
for ( var i = 2; i < 100005; i++) {
if (spf[i] == 0) {
spf[i] = i;
for ( var j = 2 * i; j < 100005; j += i) {
if (spf[j] == 0)
spf[j] = i;
}
}
}
}
function factorize(n, s)
{
while (n > 1) {
var z = spf[n];
s.add(z);
while (n % z == 0)
n = parseInt(n/z);
}
return s;
}
var id = Array(100005).fill(0);
var par =Array(100005).fill(0);
var sizeContainer = Array(100005).fill(0);
function root(i)
{
if (par[i] == i)
return i;
else
return par[i] = root(par[i]);
}
function merge(a, b)
{
var p = root(a);
var q = root(b);
if (p == q)
return ;
if (sizeContainer[p] > sizeContainer[q])
{
[p, q] = [q, p]
}
par[p] = q;
sizeContainer[q] += sizeContainer[p];
}
function maximumComponentsizeContainer(a, n)
{
for ( var i = 0; i < 100005; i++) {
par[i] = i;
sizeContainer[i] = 1;
}
sieve();
for ( var i = 0; i < n; i++) {
var s = new Set();
s = factorize(a[i], s);
s.forEach(it => {
if (id[it] == 0)
id[it] = i + 1;
else
merge(i + 1, id[it]);
});
}
var answer = 0;
for ( var i = 0; i < n; i++)
answer = Math.max(answer, sizeContainer[i]);
return answer;
}
var n = 8;
var A = [2, 3, 6, 7, 4, 12, 21, 39];
document.write( maximumComponentsizeContainer(A, n));
</script>
|
Output:
8
Time Complexity : O(N * log(max(A)))
Auxiliary Space: O(105)
Share your thoughts in the comments
Please Login to comment...