Open In App

Count the number of Prime Cliques in an undirected graph

Improve
Improve
Like Article
Like
Save
Share
Report

Given a graph with N nodes and E edges, the task is to count the number of clique having their size as a prime number or prime number of nodes in the given graph. 

A clique is a complete subgraph of a given graph.

Examples:

Input: N = 5, edges[] = { {1, 2}, {2, 3}, {3, 1}, {4, 3}, {4, 5}, {5, 3} } 
 

Output:
Explanation: 
In the given undirected graph, 1->2->3 and 3->4->5 are the two complete subgraphs, both of them are of size 3 which is a prime. 
Also, 1-2, 2->3, 3->1, 4->3, 4->5 and 5->3 are complete subgraphs of size 2. 
Hence there are 8 prime cliques. 

Approach: To solve the problem mentioned above, the main idea is to use recursion. All the vertices whose degree is greater than or equal to (K-1) are found and checked which subset of K vertices form a clique. When another edge is added to the present list, it is checked if by adding that edge, the list still forms a clique or not. The following steps can be followed to compute the result: 

  • To check if the clique size is prime or not, the idea is to use Sieve Of eratosthenes. Create a sieve which will help us to identify if the size is prime or not in O(1) time.
  • Form a recursive function with three parameters starting node, length of the present set of nodes and prime array (to check the prime numbers).
  • The starting index resembles that no node can be added to the present set less than that index. So a loop is run from that index to n.
  • Find that after adding a node to the present set, the set of nodes remains a clique. If yes, that node is added, then the current clique size is checked, if it is prime then the answer is increased by 1 and then the recursive function is called with parameters index of new added node + 1, length of current set + 1 and the prime array.
  • The vertices are added until the list does not form a clique. In the end, the answer containing the number of prime cliques is printed.

Below is the implementation of the above approach: 

C++




// C++ implementation to Count the number
// of Prime Cliques in an undirected graph
 
#include <bits/stdc++.h>
using namespace std;
 
const int MAX = 100;
 
// Stores the vertices
int store[MAX], n;
 
// Graph
int graph[MAX][MAX];
 
// Degree of the vertices
int d[MAX];
 
// To store the count of prime cliques
int ans;
 
// Function to create
// Sieve to check primes
void SieveOfEratosthenes(
    bool prime[], int p_size)
{
    // false here indicates
    // that it is not prime
    prime[0] = false;
    prime[1] = false;
 
    for (int p = 2; p * p <= p_size; p++) {
 
        // Condition if prime[p]
        // is not changed,
        // then it is a prime
        if (prime[p]) {
 
            // Update all multiples of p,
            // set them to non-prime
            for (int i = p * 2; i <= p_size; i += p)
                prime[i] = false;
        }
    }
}
 
// Function to check
// if the given set of
// vertices in store array
// is a clique or not
bool is_clique(int b)
{
 
    // Run a loop for all set of edges
    for (int i = 1; i < b; i++) {
        for (int j = i + 1; j < b; j++)
 
            // If any edge is missing
            if (graph[store[i]][store[j]] == 0)
                return false;
    }
    return true;
}
 
// Function to find the count of
// all the cliques having prime size
void primeCliques(int i, int l,
                  bool prime[])
{
    // Check if any vertices from i+1
    // can be inserted
    for (int j = i + 1; j <= n; j++) {
 
        // Add the vertex to store
        store[l] = j;
 
        // If the graph is not
        // a clique of size k then
        // it cannot be a clique
        // by adding another edge
        if (is_clique(l + 1)) {
 
            // increase the count of
            // prime cliques if the size
            // of current clique is prime
            if (prime[l])
                ans++;
 
            // Check if another edge
            // can be added
            primeCliques(j, l + 1, prime);
        }
    }
}
 
// Driver code
int main()
{
    int edges[][2] = { { 1, 2 },
                       { 2, 3 },
                       { 3, 1 },
                       { 4, 3 },
                       { 4, 5 },
                       { 5, 3 } };
 
    int size = sizeof(edges)
               / sizeof(edges[0]);
    n = 5;
 
    bool prime[n + 1];
    memset(prime, true, sizeof(prime));
 
    SieveOfEratosthenes(prime, n + 1);
 
    for (int i = 0; i < size; i++) {
        graph[edges[i][0]][edges[i][1]] = 1;
        graph[edges[i][1]][edges[i][0]] = 1;
        d[edges[i][0]]++;
        d[edges[i][1]]++;
    }
 
    ans = 0;
    primeCliques(0, 1, prime);
 
    cout << ans << "\n";
 
    return 0;
}


Java




// Java implementation to Count the number
// of Prime Cliques in an undirected graph
import java.io.*;
import java.util.*;
 
class GFG {
     
static final int MAX = 100;
 
// Stores the vertices
static int[] store = new int[MAX];
static int n;
 
// Graph
static int[][] graph = new int[MAX][MAX];
 
// Degree of the vertices
static int[] d = new int[MAX];
 
// To store the count of prime cliques
static int ans;
 
// Function to create
// Sieve to check primes
static void SieveOfEratosthenes(boolean prime[],
                                int p_size)
{
     
    // False here indicates
    // that it is not prime
    prime[0] = false;
    prime[1] = false;
 
    for(int p = 2; p * p <= p_size; p++)
    {
         
       // Condition if prime[p]
       // is not changed,
       // then it is a prime
       if (prime[p])
       {
            
           // Update all multiples of p,
           // set them to non-prime
            for(int i = p * 2; i <= p_size; i += p)
               prime[i] = false;
       }
    }
}
 
// Function to check
// if the given set of
// vertices in store array
// is a clique or not
static boolean is_clique(int b)
{
 
    // Run a loop for all set of edges
    for(int i = 1; i < b; i++)
    {
       for(int j = i + 1; j < b; j++)
        
          // If any edge is missing
          if (graph[store[i]][store[j]] == 0)
             return false;
    }
    return true;
}
 
// Function to find the count of
// all the cliques having prime size
static void primeCliques(int i, int l,
                         boolean prime[])
{
     
    // Check if any vertices from i+1
    // can be inserted
    for(int j = i + 1; j <= n; j++)
    {
        
       // Add the vertex to store
       store[l] = j;
        
       // If the graph is not
       // a clique of size k then
       // it cannot be a clique
       // by adding another edge
       if (is_clique(l + 1))
       {
            
           // Increase the count of
           // prime cliques if the size
           // of current clique is prime
           if (prime[l])
               ans++;
                
           // Check if another edge
           // can be added
           primeCliques(j, l + 1, prime);
       }
    }
}
     
// Driver code
public static void main(String[] args)
{
    int edges[][] = { { 1, 2 },
                      { 2, 3 },
                      { 3, 1 },
                      { 4, 3 },
                      { 4, 5 },
                      { 5, 3 } };
 
    int size = edges.length;
    n = 5;
 
    boolean[] prime = new boolean[n + 1];
    Arrays.fill(prime, true);
 
    SieveOfEratosthenes(prime, n);
 
    for(int i = 0; i < size; i++)
    {
       graph[edges[i][0]][edges[i][1]] = 1;
       graph[edges[i][1]][edges[i][0]] = 1;
       d[edges[i][0]]++;
       d[edges[i][1]]++;
    }
     
    ans = 0;
    primeCliques(0, 1, prime);
 
    System.out.println(ans);
}
}
 
// This code is contributed by coder001


Python3




# Python3 implementation to Count the number
# of Prime Cliques in an undirected graph
MAX = 100
  
# Stores the vertices
store = [0 for i in range(MAX)]
n = 0
  
# Graph
graph = [[0 for j in range(MAX)]
            for i in range(MAX)]
  
# Degree of the vertices
d = [0 for i in range(MAX)]
  
# To store the count of prime cliques
ans = 0
  
# Function to create
# Sieve to check primes
def SieveOfEratosthenes(prime, p_size):
     
    # false here indicates
    # that it is not prime
    prime[0] = False
    prime[1] = False
     
    p = 2
     
    while (p * p <= p_size):
         
        # Condition if prime[p]
        # is not changed,
        # then it is a prime
        if (prime[p]):
             
            # Update all multiples of p,
            # set them to non-prime
            for i in range(p * 2, p_size + 1, p):
                prime[i] = False
                 
        p += 1
         
# Function to check if the given
# set of vertices in store array
# is a clique or not
def is_clique(b):
  
    # Run a loop for all set of edges
    for i in range(1, b):
        for j in range(i + 1, b):
  
            # If any edge is missing
            if (graph[store[i]][store[j]] == 0):
                return False
     
    return True
 
# Function to find the count of
# all the cliques having prime size
def primeCliques(i, l, prime):
     
    global ans
     
    # Check if any vertices from i+1
    # can be inserted
    for j in range(i + 1, n + 1):
  
        # Add the vertex to store
        store[l] = j
  
        # If the graph is not
        # a clique of size k then
        # it cannot be a clique
        # by adding another edge
        if (is_clique(l + 1)):
  
            # Increase the count of
            # prime cliques if the size
            # of current clique is prime
            if (prime[l]):
                ans += 1
  
            # Check if another edge
            # can be added
            primeCliques(j, l + 1, prime)
     
# Driver code
if __name__=='__main__':
     
    edges = [ [ 1, 2 ], [ 2, 3 ],
              [ 3, 1 ], [ 4, 3 ],
              [ 4, 5 ], [ 5, 3 ] ]
     
    size = len(edges)
     
    n = 5
  
    prime = [True for i in range(n + 2)]
  
    SieveOfEratosthenes(prime, n + 1)
  
    for i in range(size):
        graph[edges[i][0]][edges[i][1]] = 1
        graph[edges[i][1]][edges[i][0]] = 1
        d[edges[i][0]] += 1
        d[edges[i][1]] += 1
     
    ans = 0
    primeCliques(0, 1, prime)
     
    print(ans)
 
# This code is contributed by rutvik_56


C#




// C# implementation to count the number
// of Prime Cliques in an undirected graph
using System;
 
class GFG{
     
static readonly int MAX = 100;
 
// Stores the vertices
static int[] store = new int[MAX];
static int n;
 
// Graph
static int[,] graph = new int[MAX, MAX];
 
// Degree of the vertices
static int[] d = new int[MAX];
 
// To store the count of prime cliques
static int ans;
 
// Function to create
// Sieve to check primes
static void SieveOfEratosthenes(bool []prime,
                                int p_size)
{
     
    // False here indicates
    // that it is not prime
    prime[0] = false;
    prime[1] = false;
 
    for(int p = 2; p * p <= p_size; p++)
    {
        
       // Condition if prime[p]
       // is not changed,
       // then it is a prime
       if (prime[p])
       {
            
           // Update all multiples of p,
           // set them to non-prime
           for(int i = p * 2; i <= p_size;
                   i += p)
              prime[i] = false;
       }
    }
}
 
// Function to check if the given
// set of vertices in store array
// is a clique or not
static bool is_clique(int b)
{
 
    // Run a loop for all set of edges
    for(int i = 1; i < b; i++)
    {
       for(int j = i + 1; j < b; j++)
        
          // If any edge is missing
          if (graph[store[i],store[j]] == 0)
              return false;
    }
    return true;
}
 
// Function to find the count of
// all the cliques having prime size
static void primeCliques(int i, int l,
                         bool []prime)
{
     
    // Check if any vertices from i+1
    // can be inserted
    for(int j = i + 1; j <= n; j++)
    {
        
       // Add the vertex to store
       store[l] = j;
        
       // If the graph is not
       // a clique of size k then
       // it cannot be a clique
       // by adding another edge
       if (is_clique(l + 1))
       {
            
           // Increase the count of
           // prime cliques if the size
           // of current clique is prime
           if (prime[l])
               ans++;
            
           // Check if another edge
           // can be added
           primeCliques(j, l + 1, prime);
       }
    }
}
     
// Driver code
public static void Main(String[] args)
{
    int [,]edges = { { 1, 2 },
                     { 2, 3 },
                     { 3, 1 },
                     { 4, 3 },
                     { 4, 5 },
                     { 5, 3 } };
                      
    int size = edges.GetLength(0);
    n = 5;
 
    bool[] prime = new bool[n + 1];
    for(int i = 0; i < prime.Length; i++)
       prime[i] = true;
 
    SieveOfEratosthenes(prime, n);
 
    for(int i = 0; i < size; i++)
    {
       graph[edges[i, 0],edges[i, 1]] = 1;
       graph[edges[i, 1],edges[i, 0]] = 1;
       d[edges[i, 0]]++;
       d[edges[i, 1]]++;
    }
     
    ans = 0;
    primeCliques(0, 1, prime);
 
    Console.WriteLine(ans);
}
}
 
// This code is contributed by Princi Singh


Javascript




<script>
    // Javascript implementation to count the number
    // of Prime Cliques in an undirected graph
     
    let MAX = 100;
  
    // Stores the vertices
    let store = new Array(MAX);
    store.fill(0);
    let n;
 
    // Graph
    let graph = new Array(MAX);
    for(let i = 0; i < MAX; i++)
    {
        graph[i] = new Array(MAX);
    }
 
    // Degree of the vertices
    let d = new Array(MAX);
    d.fill(0);
 
    // To store the count of prime cliques
    let ans;
 
    // Function to create
    // Sieve to check primes
    function SieveOfEratosthenes(prime, p_size)
    {
 
        // False here indicates
        // that it is not prime
        prime[0] = false;
        prime[1] = false;
 
        for(let p = 2; p * p <= p_size; p++)
        {
 
           // Condition if prime[p]
           // is not changed,
           // then it is a prime
           if (prime[p])
           {
 
               // Update all multiples of p,
               // set them to non-prime
               for(let i = p * 2; i <= p_size;
                       i += p)
                  prime[i] = false;
           }
        }
    }
 
    // Function to check if the given
    // set of vertices in store array
    // is a clique or not
    function is_clique(b)
    {
 
        // Run a loop for all set of edges
        for(let i = 1; i < b; i++)
        {
           for(let j = i + 1; j < b; j++)
 
              // If any edge is missing
              if (graph[store[i]][store[j]] == 0)
              {
                  return false;
              }
        }
        return true;
    }
 
    // Function to find the count of
    // all the cliques having prime size
    function primeCliques(i, l, prime)
    {
 
        // Check if any vertices from i+1
        // can be inserted
        for(let j = i + 1; j <= n; j++)
        {
 
           // Add the vertex to store
           store[l] = j;
 
           // If the graph is not
           // a clique of size k then
           // it cannot be a clique
           // by adding another edge
           if (is_clique(l + 1))
           {
 
               // Increase the count of
               // prime cliques if the size
               // of current clique is prime
               if (prime[l])
                   ans++;
               else
               {
                   ans-=1.3;
               }
              
               // Check if another edge
               // can be added
               primeCliques(j, l + 1, prime);
           }
        }
    }
     
    let edges = [ [ 1, 2 ],
                     [ 2, 3 ],
                     [ 3, 1 ],
                     [ 4, 3 ],
                     [ 4, 5 ],
                     [ 5, 3 ] ];
                       
    let size = edges.length;
    n = 5;
  
    let prime = new Array(n + 1);
    for(let i = 0; i < prime.length; i++)
       prime[i] = true;
  
    SieveOfEratosthenes(prime, n);
  
    for(let i = 0; i < size; i++)
    {
       graph[edges[i][0],edges[i][1]] = 1;
       graph[edges[i][1],edges[i][0]] = 1;
       d[edges[i][0]]++;
       d[edges[i][1]]++;
    }
      
    ans = 0;
    primeCliques(0, 1, prime);
  
    document.write(ans);
 
// This code is contributed by suresh07.
</script>


Output: 

8

 



Last Updated : 12 Oct, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads