Find all cliques of size K in an undirected graph

Given an undirected graph with N nodes and E edges and a value K, the task is to print all set of nodes which form a K size clique.
A clique is a complete subgraph of a graph.

Examples:


Input: N = 5, edges[] = { {1, 2}, {2, 3}, {3, 1}, {4, 3}, {4, 5}, {5, 3} }, K = 3
Output: 1 2 3, 3 4 5
Explanation: Clearly from the image, 1->2->3 and 3->4->5 are the two complete subgraphs.



Input: N = 4, edges[] = { {1, 2}, {2, 3}, {3, 1}, {4, 3} }, k = 3
Output: 1 2 3
Explanation: Subgraph 1-> 2->3 forms a complete subgraph from the given graph.

Approach: The idea is to use recursion to solve the above problem. 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:

  • Form a recursive function with three parameters starting node, length of the present set of nodes and desired length of nodes.
  • 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.
  • If it is found that after adding a node to the present set, the set of nodes remains a clique. If yes, that node is added and the recursive function is called with parameters index of new added node +1, length of current set + 1 and the desired length.
  • If the desired length is reached, the nodes are printed.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#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];
  
// 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 the set of edges
    // for the select vertex
    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 print the clique
void print(int n)
{
    for (int i = 1; i < n; i++)
        cout << store[i] << " ";
    cout << ", ";
}
  
// Function to find all the cliques of size s
void findCliques(int i, int l, int s)
{
    // Check if any vertices from i+1 can be inserted
    for (int j = i + 1; j <= n - (s - l); j++)
  
        // If the degree of the graph is sufficient
        if (d[j] >= s - 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))
  
                // If the length of the clique is
                // still less than the desired size
                if (l < s)
  
                    // Recursion to add vertices
                    findCliques(j, l + 1, s);
  
                // Size is met
                else
                    print(l + 1);
        }
}
  
// Driver code
int main()
{
    int edges[][2] = { { 1, 2 },
                       { 2, 3 },
                       { 3, 1 },
                       { 4, 3 },
                       { 4, 5 },
                       { 5, 3 } },
        k = 3;
    int size = sizeof(edges) / sizeof(edges[0]);
    n = 5;
  
    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]]++;
    }
  
    findCliques(0, 1, k);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
class GFG
{
  
static 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];
  
// 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 the set of edges
    // for the select vertex
    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 print the clique
static void print(int n)
{
    for (int i = 1; i < n; i++)
        System.out.print(store[i] + " ");
    System.out.print(", ");
}
  
// Function to find all the cliques of size s
static void findCliques(int i, int l, int s)
{
    // Check if any vertices from i+1 can be inserted
    for (int j = i + 1; j <= n - (s - l); j++)
  
        // If the degree of the graph is sufficient
        if (d[j] >= s - 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))
  
                // If the length of the clique is
                // still less than the desired size
                if (l < s)
  
                    // Recursion to add vertices
                    findCliques(j, l + 1, s);
  
                // Size is met
                else
                    print(l + 1);
        }
}
  
// Driver code
public static void main(String[] args)
{
    int edges[][] = { { 1, 2 },
                    { 2, 3 },
                    { 3, 1 },
                    { 4, 3 },
                    { 4, 5 },
                    { 5, 3 } },
    k = 3;
    int size = edges.length;
    n = 5;
  
    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]]++;
    }
  
    findCliques(0, 1, k);
}
}
  
// This code is contributed by 29AjayKumar

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
import numpy as np
  
MAX = 100
  
# Stores the vertices 
store = [0]* MAX
  
# Graph 
graph = np.zeros((MAX, MAX)); 
  
# Degree of the vertices 
d = [0] * MAX
  
# 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 the set of edges 
    # for the select vertex 
    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 print the clique 
def print_cli(n) : 
  
    for i in range(1, n) :
        print(store[i], end = " "); 
    print(",", end=" "); 
  
# Function to find all the cliques of size s 
def findCliques(i, l, s) :
  
    # Check if any vertices from i+1 can be inserted 
    for j in range( i + 1, n -(s - l) + 1) : 
  
        # If the degree of the graph is sufficient 
        if (d[j] >= s - 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)) :
  
                # If the length of the clique is 
                # still less than the desired size 
                if (l < s) :
  
                    # Recursion to add vertices 
                    findCliques(j, l + 1, s); 
  
                # Size is met 
                else :
                    print_cli(l + 1); 
  
# Driver code 
if __name__ == "__main__"
  
    edges = [ [ 1, 2 ], 
              [ 2, 3 ], 
              [ 3, 1 ], 
              [ 4, 3 ], 
              [ 4, 5 ], 
              [ 5, 3 ] ];
    k = 3
    size = len(edges); 
    n = 5
  
    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
      
  
    findCliques(0, 1, k); 
  
# This code is contributed by AnkitRai01

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach 
using System;
  
class GFG 
  
    static 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]; 
      
    // 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 the set of edges 
        // for the select vertex 
        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 print the clique 
    static void print(int n) 
    
        for (int i = 1; i < n; i++) 
            Console.Write(store[i] + " "); 
        Console.Write(", "); 
    
      
    // Function to find all the cliques of size s 
    static void findCliques(int i, int l, int s) 
    
        // Check if any vertices from i+1 can be inserted 
        for (int j = i + 1; j <= n - (s - l); j++) 
      
            // If the degree of the graph is sufficient 
            if (d[j] >= s - 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)) 
      
                    // If the length of the clique is 
                    // still less than the desired size 
                    if (l < s) 
      
                        // Recursion to add vertices 
                        findCliques(j, l + 1, s); 
      
                    // Size is met 
                    else
                        print(l + 1); 
            
    
      
    // Driver code 
    public static void Main() 
    
        int [,]edges = { { 1, 2 }, 
                        { 2, 3 }, 
                        { 3, 1 }, 
                        { 4, 3 }, 
                        { 4, 5 }, 
                        { 5, 3 } };
        int k = 3; 
        int size = edges.GetLength(0); 
        n = 5; 
      
        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]]++; 
        
      
        findCliques(0, 1, k); 
    
  
// This code is contributed by AnkitRai01

chevron_right


Output:

1 2 3 , 3 4 5 ,

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : 29AjayKumar, AnkitRai01