Open In App

Count of Disjoint Groups by grouping points that are at most K distance apart

Last Updated : 23 Nov, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given a 2D array arr[] and value K, where each list in arr[] represents a point on Cartesian coordinates, the task is to group the given points if the distance between them is less than or equal to K and find the total number of disjoint groups. 

Note: If points ‘a’ and ‘b’ are in the same group and ‘a’, ‘d’ are in the same group then ‘b’ and ‘d’ are also in the same group.

Examples:

Input: arr[] = {{73, -62}, {2, 2}, {3, 3}}, K = 1
Output: 3
Explanation: There are no two points which have distance = 1.
So all three points form different disjoint sets.

Input: arr[] = {{3, 6}, {4, 2}, {3, 3}, {4, 9}}, K = 2
Output: 3
Explanation: The points{4, 2} and {3, 3} form a group.

An approach using Disjoint set union:

The idea to solve this problem is based on the concept of disjoint set union

Assume all points as a disjoint group. So, number of disjoint groups initially will be N (N is the number of points in the given array). Generate all the possible pairs of points in the given array arr[], then check if the distance between them is less than or equals to K or not. If condition is satisfied, then merge them together and reduce the count of number of disjoint sets by 1.

Follow the steps below to implement the above idea:

  • Create a parent and rank array of size N, where N is the number of points in the given array and a variable (say cc) to store the number of the connected components and initialize cc by N.
  • Initialize the parent array for ith point to i (i.e parent[i] = i) and rank[i] = 1.
  • Generate all the possible pairs of points in the given array arr
  • Calculate the distance between the point and check if the distance between them is less than or equal to K or not
    • if the distance is less the equal to k,  
      • Call the union1 function to merge these points.
      • If merge is done successfully then reduce the count of cc by 1.
  • Finally, return the count of cc.

Below is the implementation of the above approach:

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the parent of a node
int find(int x, vector<int>& parent)
{
    if (x == parent[x])
        return x;
 
    return parent[x] = find(parent[x], parent);
}
 
// Function to unite two sets
bool union1(int x, int y, vector<int>& parent,
            vector<int>& rank)
{
    int lx = find(x, parent);
    int ly = find(y, parent);
 
    // Condition of merging
    if (lx != ly) {
        if (rank[lx] > rank[ly]) {
            parent[ly] = lx;
        }
        else if (rank[lx] < rank[ly]) {
            parent[lx] = ly;
        }
        else {
            parent[lx] = ly;
            rank[ly] += 1;
        }
 
        // Return true for merging two
        // groups into one groups
        return true;
    }
 
    // Return false if points are
    // already merged.
    return false;
}
 
// Function to count the number of groups
// formed after grouping the points
int solve(vector<vector<int> >& points, int k)
{
    int n = points.size(),
 
        // cc is for number of
        // connected component
        cc = n;
 
    vector<int> parent(n), rank(n);
 
    for (int i = 0; i < n; i++) {
        parent[i] = i;
        rank[i] = 1;
    }
 
    // Iterate over all pairs of point
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
 
            double x1 = points[i][0], y1 = points[i][1];
            double x2 = points[j][0], y2 = points[j][1];
 
            // Calculate the distance
            // between the points
            double dist = (double)sqrt(pow(x2 - x1, 2)
                                       + pow(y2 - y1, 2));
 
            // Check the given condition
            if (dist <= k) {
 
                // Merge this pair of points
                // into one group
                bool merge = union1(i, j, parent, rank);
 
                // If these points are getting
                // merged then reduce the cc by 1;
                if (merge)
                    cc--;
            }
        }
    }
 
    return cc;
}
 
// Driver code
int main()
{
    vector<vector<int> > arr
        = { { 73, -62 }, { 2, 2 }, { 3, 3 } };
    int K = 1;
    int result = solve(arr, K);
 
    // Function Call
    cout << result << endl;
    return 0;
}


Java




// Java code to implement the approach
import java.io.*;
 
class GFG
{
   
  // Function to find the parent of a node
  public static int find(int x, int parent[])
  {
    if (x == parent[x])
      return x;
 
    return parent[x] = find(parent[x], parent);
  }
 
  // Function to unite two sets
  public static boolean union1(int x, int y, int parent[],
                               int rank[])
  {
    int lx = find(x, parent);
    int ly = find(y, parent);
 
    // Condition of merging
    if (lx != ly) {
      if (rank[lx] > rank[ly]) {
        parent[ly] = lx;
      }
      else if (rank[lx] < rank[ly]) {
        parent[lx] = ly;
      }
      else {
        parent[lx] = ly;
        rank[ly] += 1;
      }
 
      // Return true for merging two
      // groups into one groups
      return true;
    }
 
    // Return false if points are
    // already merged.
    return false;
  }
 
  // Function to count the number of groups
  // formed after grouping the points
  public static int solve(int points[][], int k)
  {
    int n = points.length,
 
    // cc is for number of
    // connected component
    cc = n;
 
    int parent[] = new int[n];
    int rank[] = new int[n];
 
    for (int i = 0; i < n; i++) {
      parent[i] = i;
      rank[i] = 1;
    }
 
    // Iterate over all pairs of point
    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
 
        double x1 = points[i][0], y1 = points[i][1];
        double x2 = points[j][0], y2 = points[j][1];
 
        // Calculate the distance
        // between the points
        double dist = (double)Math.sqrt(
          Math.pow(x2 - x1, 2)
          + Math.pow(y2 - y1, 2));
 
        // Check the given condition
        if (dist <= k) {
 
          // Merge this pair of points
          // into one group
          boolean merge
            = union1(i, j, parent, rank);
 
          // If these points are getting
          // merged then reduce the cc by 1;
          if (merge == true)
            cc--;
        }
      }
    }
 
    return cc;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int arr[][] = { { 73, -62 }, { 2, 2 }, { 3, 3 } };
    int K = 1;
    int result = solve(arr, K);
 
    // Function Call
    System.out.println(result);
  }
}
 
// This code is contributed by Rohit Pradhan


Python3




import math
 
class GFG :
   
    # Function to find the parent of a node
    @staticmethod
    def  find( x,  parent) :
        if (x == parent[x]) :
            return x
        return
        parent[x] = GFG.find(parent[x], parent)
         
    # Function to unite two sets
    @staticmethod
    def  union1( x,  y,  parent,  rank) :
        lx = GFG.find(x, parent)
        ly = GFG.find(y, parent)
         
        # Condition of merging
        if (lx != ly) :
            if (rank[lx] > rank[ly]) :
                parent[ly] = lx
            elif(rank[lx] < rank[ly]) :
                parent[lx] = ly
            else :
                parent[lx] = ly
                rank[ly] += 1
                 
            # Return true for merging two
            # groups into one groups
            return True
           
        # Return false if points are
        # already merged.
        return False
       
    # Function to count the number of groups
    # formed after grouping the points
    @staticmethod
    def  solve( points,  k) :
        n = len(points)
        cc = n
        parent = [0] * (n)
        rank = [0] * (n)
        i = 0
        while (i < n) :
            parent[i] = i
            rank[i] = 1
            i += 1
             
        # Iterate over all pairs of point
        i = 0
        while (i < n) :
            j = i + 1
            while (j < n) :
                x1 = points[i][0]
                y1 = points[i][1]
                x2 = points[j][0]
                y2 = points[j][1]
                 
                # Calculate the distance
                # between the points
                dist = float(math.sqrt(math.pow(x2 - x1,2) + math.pow(y2 - y1,2)))
                 
                # Check the given condition
                if (dist <= k) :
                   
                    # Merge this pair of points
                    # into one group
                    merge = GFG.union1(i, j, parent, rank)
                     
                    # If these points are getting
                    # merged then reduce the cc by 1;
                    if (merge == True) :
                        cc -= 1
                j += 1
            i += 1
        return cc
       
    # Driver Code
    @staticmethod
    def main( args) :
        arr = [[73, -62], [2, 2], [3, 3]]
        K = 1
        result = GFG.solve(arr, K)
         
        # Function Call
        print(result)
     
if __name__=="__main__":
    GFG.main([])
     
    # This code is contributed by aadityaburujwale.


C#




// C# code to implement the approach
using System;
class GFG
{
   
    // Function to find the parent of a node
    static int find(int x, int[] parent)
    {
        if (x == parent[x])
            return x;
 
        return parent[x] = find(parent[x], parent);
    }
 
    // Function to unite two sets
    static bool union1(int x, int y, int[] parent,
                       int[] rank)
    {
        int lx = find(x, parent);
        int ly = find(y, parent);
 
        // Condition of merging
        if (lx != ly) {
            if (rank[lx] > rank[ly]) {
                parent[ly] = lx;
            }
            else if (rank[lx] < rank[ly]) {
                parent[lx] = ly;
            }
            else {
                parent[lx] = ly;
                rank[ly] += 1;
            }
 
            // Return true for merging two
            // groups into one groups
            return true;
        }
 
        // Return false if points are
        // already merged.
        return false;
    }
 
    // Function to count the number of groups
    // formed after grouping the points
    static int solve(int[, ] points, int k, int n, int m)
    {
 
        // cc is for number of
        // connected component
        int cc = n;
        int[] parent = new int[n];
        int[] rank = new int[n];
        for (int i = 0; i < n; i++) {
            parent[i] = i;
            rank[i] = 1;
        }
 
        // Iterate over all pairs of point
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
 
                double x1 = (double)points[i, 0],
                       y1 = (double)points[i, 1];
                double x2 = (double)points[j, 0],
                       y2 = (double)points[j, 1];
 
                // Calculate the distance
                // between the points
                double dist = (double)Math.Sqrt(
                    Math.Pow(x2 - x1, 2)
                    + Math.Pow(y2 - y1, 2));
 
                // Check the given condition
                if (dist <= k) {
 
                    // Merge this pair of points
                    // into one group
                    bool merge = union1(i, j, parent, rank);
 
                    // If these points are getting
                    // merged then reduce the cc by 1;
                    if (merge)
                        cc--;
                }
            }
        }
 
        return cc;
    }
 
    // Driver code
    public static void Main(string[] args)
    {
 
        int[, ] arr = new int[3, 2] { { 73, -62 },
                                      { 2, 2 },
                                      { 3, 3 } };
        int N = 3;
        int M = 2;
        int K = 1;
        int result = solve(arr, K, N, M);
 
        // Function Call
        Console.Write(result);
    }
}
 
// This code is contributed by garg28harsh.


Javascript




<script>
    // JavaScript code to implement the approach
 
    // Function to find the parent of a node
    const find = (x, parent) => {
        if (x == parent[x])
            return x;
 
        return parent[x] = find(parent[x], parent);
    }
 
    // Function to unite two sets
    const union1 = (x, y, parent, rank) => {
        let lx = find(x, parent);
        let ly = find(y, parent);
 
        // Condition of merging
        if (lx != ly) {
            if (rank[lx] > rank[ly]) {
                parent[ly] = lx;
            }
            else if (rank[lx] < rank[ly]) {
                parent[lx] = ly;
            }
            else {
                parent[lx] = ly;
                rank[ly] += 1;
            }
 
            // Return true for merging two
            // groups into one groups
            return true;
        }
 
        // Return false if points are
        // already merged.
        return false;
    }
 
    // Function to count the number of groups
    // formed after grouping the points
    const solve = (points, k) => {
        let n = points.length,
 
            // cc is for number of
            // connected component
            cc = n;
 
        let parent = new Array(n).fill(0), rank = new Array(n).fill(0);
 
        for (let i = 0; i < n; i++) {
            parent[i] = i;
            rank[i] = 1;
        }
 
        // Iterate over all pairs of point
        for (let i = 0; i < n; i++) {
            for (let j = i + 1; j < n; j++) {
 
                let x1 = points[i][0], y1 = points[i][1];
                let x2 = points[j][0], y2 = points[j][1];
 
                // Calculate the distance
                // between the points
                let dist = Math.sqrt(Math.pow(x2 - x1, 2)
                    + Math.pow(y2 - y1, 2));
 
                // Check the given condition
                if (dist <= k) {
 
                    // Merge this pair of points
                    // into one group
                    let merge = union1(i, j, parent, rank);
 
                    // If these points are getting
                    // merged then reduce the cc by 1;
                    if (merge)
                        cc--;
                }
            }
        }
 
        return cc;
    }
 
    // Driver code
    let arr = [[73, -62], [2, 2], [3, 3]];
    let K = 1;
    let result = solve(arr, K);
 
    // Function Call
    document.write(result);
 
    // This code is contributed by rakeshsahni
 
</script>


Output

3

Time Complexity: O(N2), where N is the number of points in the given array.
Auxiliary Space: O(N), for storing the parents and rank array in UnionFind.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads