Find all cliques of size K in an undirected graph - GeeksforGeeks

25 Aug, 2021
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++
Java
Python3
C#
Javascript
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std; const int MAX = 100; // Stores the verticesint store[MAX], n; // Graphint graph[MAX][MAX]; // Degree of the verticesint d[MAX]; // Function to check if the given set of vertices// in store array is a clique or notbool 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 cliquevoid print(int n){    for (int i = 1; i < n; i++)        cout << store[i] << " ";    cout << ", ";} // Function to find all the cliques of size svoid 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 codeint 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;}
// Java implementation of the approachclass GFG{ static int MAX = 100; // Stores the verticesstatic int []store = new int[MAX];static int n; // Graphstatic int [][]graph = new int [MAX][MAX]; // Degree of the verticesstatic int []d = new int[MAX]; // Function to check if the given set of vertices// in store array is a clique or notstatic 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 cliquestatic 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 sstatic 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 codepublic 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
# Python3 implementation of the approachimport numpy as np MAX = 100; # Stores the verticesstore = [0]* MAX; # Graphgraph = np.zeros((MAX, MAX)); # Degree of the verticesd = [0] * MAX; # Function to check if the given set of vertices# in store array is a clique or notdef 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 cliquedef print_cli(n) :     for i in range(1, n) :        print(store[i], end = " ");    print(",", end=" "); # Function to find all the cliques of size sdef 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 codeif __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
// C# implementation of the approachusing 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
<script>    // JavaScript implementation of the approach    const MAX = 100;     // Stores the vertices    let store = new Array(MAX).fill(0), n = 0;         // Graph    let graph = new Array(MAX).fill(0).map(() => new Array(MAX).fill(0));     // Degree of the vertices    let d = new Array(MAX).fill(0);     // Function to check if the given set of vertices    // in store array is a clique or not    const is_clique = (b) => {             // Run a loop for all the set of edges        // for the select vertex        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 print the clique    const print = (n) => {        for (let i = 1; i < n; i++)            document.write(`${store[i]} `);        document.write(", ");    }     // Function to find all the cliques of size s    const findCliques = (i, l, s) => {             // Check if any vertices from i+1 can be inserted        for (let 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    const edges = [        [1, 2],        [2, 3],        [3, 1],        [4, 3],        [4, 5],        [5, 3]    ];         let k = 3;    let size = edges.length;    n = 5;     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]]++;    }     findCliques(0, 1, k);         // This code is contributed by rakeshsahni </script>
1 2 3 , 3 4 5 ,
 
29AjayKumar
ankthon
rakeshsahni
Technical Scripter 2019
Graph
Recursion
Technical Scripter
Recursion
Graph
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Topological Sorting
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16
Detect Cycle in a Directed Graph
Write a program to print all permutations of a given string
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Recursion
Program for Tower of Hanoi
Backtracking | Introduction