Open In App

Minimize rope length to connect given points in a 3D plane

Last Updated : 08 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a 2-D array A[][] of size N × 3, where each element of the array is of the form {x, y, z}, where x, y and z are coordinates of a point in 3D space. The task is to connect all the points such that the total length of the rope is minimized.

Note: The length of rope use to connect two points  A1(x1, y1, z1) and A2(x2, y2, z2) is given as: min( |x1-x2|, |y1-y2|, |z1-z2| )

Examples:

Input: A[][] = { {1, 2, 3}, {6, 8, 1}, {5, 3, 4}, {8, 5, 6} }
Output: 4
Explanation: Minimum edges use to connect all edge
Distance of P1 and P3 is 1.
Distance of P2 and P3 is 1.
Distance of P4 and P3 is 2.
Total length of rope used = 1 + 1 + 2 = 4

Input: A[][] = { {0, 5, 0}, {8, 5, 0}, {0, 1, 56} }
Output: 0
Explanation: Minimum edges use to connect all edge
Distance of P1 and P2 is 0.
Distance of P1 and P3 is 0. 
Total length of rope used = 0 + 0 = 0

Naive Approach: The basic idea is to connect all the points and form a graph. Then check all the possible combinations of edges and find the minimum among them.

Time Complexity: O(N^2CN) as there can be total N(N-1) edges and we will only need (N-1) edges from those to connect the graph.
Auxiliary Space: O(N)

Minimize rope cost to connect the points by using Minimum Spanning Tree

This problem can also be solved based on the minimum spanning tree (MST) concept. 

We will need to make a graph where the weight of each edge is the same as the distance between the points. The MST formed from that graph will have the minimum total distance among the points and so the required rope length will also be minimum.

Instead of connecting all the points we can build three separate graphs from the distances among the coordinates of each of the axis separately because of the special property of the distance. Consider those edges and use the concept of MST.

Follow the steps below to implement the idea:

  • Length of rope required to connect two points depends only on one axis whose difference is minimum.
  • So all the axis can be evaluated separately.
  • Sort all three coordinates separately.
  • Construct edges with edge weight equal to the difference of consecutive coordinates for all three axes separately.
  • Run the minimum spanning tree algorithm on the graph to find the minimum length of rope needed.

Code implementation of the above approach: 

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
vector<vector<int> > edges;
 
int findparent(int a, vector<int>& parentOf)
{
    if (parentOf[a] == -1)
        return a;
    return parentOf[a] = findparent(parentOf[a], parentOf);
}
 
void union_set(int a, int b, vector<int>& parentOf,
               vector<int>& rank)
{
    int s1 = findparent(a, parentOf);
    int s2 = findparent(b, parentOf);
 
    if (s1 != s2) {
        int r1 = rank[s1];
        int r2 = rank[s2];
        if (r1 >= r2) {
            parentOf[s2] = s1;
            rank[s1] = r1 + r2;
        }
        else {
            parentOf[s1] = s2;
            rank[s2] = r1 + r2;
        }
    }
}
int calculatemst(int N)
{
    int cost = 0;
    vector<int> rank(N + 1, -1);
    vector<int> parentOf(N + 1, -1);
    for (int i = 0; i < edges.size(); i++) {
        int wt = edges[i][0], a = edges[i][1],
            b = edges[i][2];
        if (findparent(a, parentOf)
            != findparent(b, parentOf)) {
            cost += wt;
            union_set(a, b, parentOf, rank);
        }
    }
    return cost;
}
void graph(vector<pair<int, int> > v)
{
    for (int i = 0; i < v.size() - 1; i++) {
        int dist = v[i + 1].first - v[i].first;
        int nodeone = v[i].second;
        int nodesecond = v[i + 1].second;
        edges.push_back({ dist, nodeone, nodesecond });
    }
}
void solve(int a[][3], int N)
{
    vector<pair<int, int> > x, y, z;
    for (int i = 0; i < N; i++) {
        x.push_back({ a[i][0], i + 1 });
        y.push_back({ a[i][1], i + 1 });
        z.push_back({ a[i][2], i + 1 });
    }
    sort(x.begin(), x.end());
    sort(y.begin(), y.end());
    sort(z.begin(), z.end());
    graph(x);
    graph(y);
    graph(z);
    sort(edges.begin(), edges.end());
    return;
}
 
// Drivers code
int main()
{
    int arr[][3] = {
        { 1, 2, 3 }, { 6, 8, 1 }, { 5, 3, 4 }, { 8, 5, 6 }
    };
 
    // Function Call
    solve(arr, 4);
    cout << calculatemst(4) << endl;
}


Java




// Java code for the above approach:
import java.util.*;
 
class GFG {
  static ArrayList<ArrayList<Integer> > edges
    = new ArrayList<>();
 
  static int findparent(int a, int[] parentOf)
  {
    if (parentOf[a] == -1)
      return a;
    return parentOf[a]
      = findparent(parentOf[a], parentOf);
  }
 
  static void union_set(int a, int b, int[] parentOf,
                        int[] rank)
  {
    int s1 = findparent(a, parentOf);
    int s2 = findparent(b, parentOf);
 
    if (s1 != s2) {
      int r1 = rank[s1];
      int r2 = rank[s2];
      if (r1 >= r2) {
        parentOf[s2] = s1;
        rank[s1] = r1 + r2;
      }
      else {
        parentOf[s1] = s2;
        rank[s2] = r1 + r2;
      }
    }
  }
  static int calculatemst(int N)
  {
    int cost = 0;
    int[] rank = new int[N + 1];
    int[] parentOf = new int[N + 1];
    Arrays.fill(rank, -1);
    Arrays.fill(parentOf, -1);
 
    for (int i = 0; i < edges.size(); i++) {
      int wt = edges.get(i).get(0);
      int a = edges.get(i).get(1);
      int b = edges.get(i).get(2);
      if (findparent(a, parentOf)
          != findparent(b, parentOf)) {
        cost += wt;
        union_set(a, b, parentOf, rank);
      }
    }
    return cost;
  }
  static void graph(ArrayList<pair> v)
  {
    for (int i = 0; i < v.size() - 1; i++) {
      int dist = v.get(i + 1).first - v.get(i).first;
      int nodeone = v.get(i).second;
      int nodesecond = v.get(i + 1).second;
      ArrayList<Integer> al = new ArrayList<>();
      al.add(dist);
      al.add(nodeone);
      al.add(nodesecond);
      edges.add(al);
    }
  }
  static void solve(int a[][], int N)
  {
    ArrayList<pair> x = new ArrayList<>();
    ArrayList<pair> y = new ArrayList<>();
    ArrayList<pair> z = new ArrayList<>();
    for (int i = 0; i < N; i++) {
      x.add(new pair(a[i][0], i + 1));
      y.add(new pair(a[i][1], i + 1));
      z.add(new pair(a[i][2], i + 1));
    }
    Collections.sort(x, (pair A, pair B) -> {
      return A.first - B.first;
    });
    Collections.sort(y, (pair A, pair B) -> {
      return A.first - B.first;
    });
    Collections.sort(z, (pair A, pair B) -> {
      return A.first - B.first;
    });
    graph(x);
    graph(y);
    graph(z);
    Collections.sort(edges,
                     (ArrayList<Integer> A,
                      ArrayList<Integer> B) -> {
                       return A.get(0) - B.get(0);
                     });
    return;
  }
  static class pair {
    int first;
    int second;
    pair(int a, int b)
    {
      first = a;
      second = b;
    }
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int arr[][] = { { 1, 2, 3 },
                   { 6, 8, 1 },
                   { 5, 3, 4 },
                   { 8, 5, 6 } };
 
    // Function Call
    solve(arr, 4);
    System.out.println(calculatemst(4));
  }
}
 
// This code is contributed by karandeep1234.


Python3




# Python code for the above approach\
edges = []
 
def findparent(a, parentOf):
    if (parentOf[a] == -1):
        return a
    parentOf[a] = findparent(parentOf[a], parentOf)
    return parentOf[a]
 
def union_set(a, b, parentOf, rank):
    s1 = findparent(a, parentOf)
    s2 = findparent(b, parentOf)
 
    if (s1 != s2):
        r1 = rank[s1]
        r2 = rank[s2]
        if (r1 >= r2):
            parentOf[s2] = s1
            rank[s1] = r1 + r2
        else:
            parentOf[s1] = s2
            rank[s2] = r1 + r2
 
def calculatemst(N):
    cost = 0
    rank = [-1] * (N + 1)
    parentOf = [-1] * (N + 1)
    for i in range(len(edges)):
        wt = edges[i][0]
        a = edges[i][1]
        b = edges[i][2]
        if (findparent(a, parentOf) != findparent(b, parentOf)):
            cost += wt
            union_set(a, b, parentOf, rank)
 
    return cost
 
def graph(v):
    for i in range(len(v) - 1):
        dist = v[i + 1][0] - v[i][0]
        nodeone = v[i][1]
        nodesecond = v[i + 1][1]
        edges.append([dist, nodeone, nodesecond])
 
def solve(a, N):
    x = []
    y = []
    z = []
    for i in range(N):
        x.append([a[i][0], i + 1])
        y.append([a[i][1], i + 1])
        z.append([a[i][2], i + 1])
 
    x.sort()
    y.sort()
    z.sort()
    graph(x)
    graph(y)
    graph(z)
    edges.sort()
    return
 
# Drivers code
arr = [[1, 2, 3], [6, 8, 1], [5, 3, 4], [8, 5, 6]]
 
# Function Call
solve(arr, 4)
print(calculatemst(4))
 
# This code is contributed by Saurabh Jaiswal


C#




using System;
using System.Collections.Generic;
 
class GFG
{
  static List<List<int>> edges = new List<List<int>>();
 
  static int FindParent(int a, int[] parentOf)
  {
    if (parentOf[a] == -1)
      return a;
    return parentOf[a] = FindParent(parentOf[a], parentOf);
  }
 
  static void UnionSet(int a, int b, int[] parentOf, int[] rank)
  {
    int s1 = FindParent(a, parentOf);
    int s2 = FindParent(b, parentOf);
 
    if (s1 != s2)
    {
      int r1 = rank[s1];
      int r2 = rank[s2];
      if (r1 >= r2)
      {
        parentOf[s2] = s1;
        rank[s1] = r1 + r2;
      }
      else
      {
        parentOf[s1] = s2;
        rank[s2] = r1 + r2;
      }
    }
  }
 
  static int CalculateMst(int N)
  {
    int cost = 0;
    int[] rank = new int[N + 1];
    int[] parentOf = new int[N + 1];
    Array.Fill(rank, -1);
    Array.Fill(parentOf, -1);
 
    for (int i = 0; i < edges.Count; i++)
    {
      int wt = edges[i][0];
      int a = edges[i][1];
      int b = edges[i][2];
      if (FindParent(a, parentOf) != FindParent(b, parentOf))
      {
        cost += wt;
        UnionSet(a, b, parentOf, rank);
      }
    }
    return cost;
  }
 
  static void Graph(List<(int, int)> v)
  {
    for (int i = 0; i < v.Count - 1; i++)
    {
      int dist = v[i + 1].Item1 - v[i].Item1;
      int nodeone = v[i].Item2;
      int nodesecond = v[i + 1].Item2;
      List<int> al = new List<int> { dist, nodeone, nodesecond };
      edges.Add(al);
    }
  }
 
  static void Solve(int[,] a, int N)
  {
    List<(int, int)> x = new List<(int, int)>();
    List<(int, int)> y = new List<(int, int)>();
    List<(int, int)> z = new List<(int, int)>();
    for (int i = 0; i < N; i++)
    {
      x.Add((a[i, 0], i + 1));
      y.Add((a[i, 1], i + 1));
      z.Add((a[i, 2], i + 1));
    }
    x.Sort((a, b) => a.Item1 - b.Item1);
    y.Sort((a,b) => a.Item1 - b.Item1);
    z.Sort((a, b) => a.Item1 - b.Item1);
 
 
    Graph(x);
    Graph(y);
    Graph(z);
 
    edges.Sort((a, b) => a[0] - b[0]);
 
    return;
  }
 
  static void Graph(List<Tuple<int, int>> v)
  {
    for (int i = 0; i < v.Count - 1; i++)
    {
      int dist = v[i + 1].Item1 - v[i].Item1;
      int nodeone = v[i].Item2;
      int nodesecond = v[i + 1].Item2;
 
      List<int> al = new List<int> { dist, nodeone, nodesecond };
      edges.Add(al);
    }
  }
  static int CalculateMST(int N)
  {
    int cost = 0;
    int[] rank = new int[N + 1];
    int[] parentOf = new int[N + 1];
    for (int i = 0; i <= N; i++)
    {
      rank[i] = -1;
      parentOf[i] = -1;
    }
 
    for (int i = 0; i < edges.Count; i++)
    {
      int wt = edges[i][0];
      int a = edges[i][1];
      int b = edges[i][2];
 
      if (FindParent(a, parentOf) != FindParent(b, parentOf))
      {
        cost += wt;
        UnionSet(a, b, parentOf, rank);
      }
    }
 
    return cost;
  }
 
  static void Main(string[] args)
  {
    int[,] arr = { { 1, 2, 3 },
                  { 6, 8, 1 },
                  { 5, 3, 4 },
                  { 8, 5, 6 } };
    Solve(arr, 4);
    Console.WriteLine(CalculateMST(4));
  }
}
 
// This code is contributed by lokeshpotta20.


Javascript




<script>
        // JavaScript code for the above approach
        let edges = [];
 
        function findparent(a, parentOf) {
            if (parentOf[a] == -1)
                return a;
            return parentOf[a] = findparent(parentOf[a], parentOf);
        }
 
        function union_set(a, b, parentOf,
            rank) {
            let s1 = findparent(a, parentOf);
            let s2 = findparent(b, parentOf);
 
            if (s1 != s2) {
                let r1 = rank[s1];
                let r2 = rank[s2];
                if (r1 >= r2) {
                    parentOf[s2] = s1;
                    rank[s1] = r1 + r2;
                }
                else {
                    parentOf[s1] = s2;
                    rank[s2] = r1 + r2;
                }
            }
        }
        function calculatemst(N) {
            let cost = 0;
            let rank = new Array(N + 1).fill(-1);
            let parentOf = new Array(N + 1).fill(-1);
            for (let i = 0; i < edges.length; i++) {
                let wt = edges[i][0], a = edges[i][1],
                    b = edges[i][2];
                if (findparent(a, parentOf)
                    != findparent(b, parentOf)) {
                    cost += wt;
                    union_set(a, b, parentOf, rank);
                }
            }
            return cost;
        }
        function graph(v) {
            for (let i = 0; i < v.length - 1; i++) {
                let dist = v[i + 1][0] - v[i][0];
                let nodeone = v[i][1];
                let nodesecond = v[i + 1][1];
                edges.push([dist, nodeone, nodesecond]);
            }
        }
        function solve(a, N) {
            let x = [], y = [], z = [];
            for (let i = 0; i < N; i++) {
                x.push([a[i][0], i + 1]);
                y.push([a[i][1], i + 1]);
                z.push([a[i][2], i + 1]);
            }
            x.sort(function (a, b) { return a[0] - b[0] });
            y.sort(function (a, b) { return a[0] - b[0] });
            z.sort(function (a, b) { return a[0] - b[0] });
            graph(x);
            graph(y);
            graph(z);
            edges.sort(function (a, b) { return a[0] - b[0] })
            return;
        }
 
        // Drivers code
        let arr = [
            [1, 2, 3], [6, 8, 1], [5, 3, 4], [8, 5, 6]
        ];
 
        // Function Call
        solve(arr, 4);
        document.write(calculatemst(4));
 
 // This code is contributed by Potta Lokesh
 
    </script>


Output

4

Time complexity: O(N * log N)
Auxiliary Space: O(N)



Similar Reads

Length of rope tied around three equal circles touching each other
Given r is the radius of three equal circles touching each other. The task is to find the length of the rope tied around the circles as shown below: Examples: Input: r = 7 Output: 86 Input: r = 14 Output: 172 Approach: As it can be clearly seen from above image, the part of the length of rope which is not touching the circle is 2r + 2r + 2r = 6r. T
3 min read
Probability of cutting a rope into three pieces such that the sides form a triangle
Given a rope. We have to find the probability of cutting a rope into 3 pieces such that they form a triangle. Answer: 0.25 Explanation: Let the length of rope be 1 unit. We choose two points X and Y on the rope. Note: Formation of triangle is based on Triangle inequality i.e. sum of the lengths of any two sides of a triangle must be greater than th
2 min read
When to use Rope over StringBuilder in Java?
What are Ropes? Rope is a binary tree data structure where each node except the leaf contains the number of characters present to the left of the node. They are mainly used by text editors to store and manipulate large strings. It provides different string operations such as append, insert and delete in a faster and more efficient way. Ropes work m
3 min read
Minimum length of wire needed to connect all points who have value as 0 with at least one point with value 1.
Given two arrays Point[] and Value[] of length N, where Point[] represents the position of N points on a horizontal line. Then your task is to output the minimum length of line needed to connect all points having Value[i] = 0 with at least one point having Value[i] = 1, directly or indirectly. Note: There will be at least one point with value = 1.
12 min read
Find the equation of plane which passes through two points and parallel to a given axis
Given two points A(x1, y1, z1) and B(x2, y2, z2) and a set of points (a, b, c) which represent the axis (ai + bj + ck), the task is to find the equation of plane which passes through the given points A and B and parallel to the given axis. Examples: Input: x1 = 1, y1 = 2, z1 = 3, x2 = 3, y2 = 4, z2 = 5, a= 6, b = 7, c = 8 Output: 2x + 4y + 2z + 0 =
9 min read
Check if any point exists in a plane whose Manhattan distance is at most K from N given points
Given two arrays A[] and B[] consisting of X and Y coordinates of N distinct points in a plane, and a positive integer K, the task is to check if there exists any point P in the plane such that the Manhattan distance between the point and all the given points is at most K. If there exists any such point P, then print "Yes". Otherwise, print "No". E
7 min read
Minimize the maximum distance between adjacent points after adding K points anywhere in between
Given an array arr[] of N integers representing the position of N points along a straight line and an integer K, the task is to find the minimum value of the maximum distance between adjacent points after adding K points anywhere in between, not necessarily on an integer position. Examples: Input: arr[] = {2, 4, 8, 10}, K = 1Output: 2Explanation: A
9 min read
Minimum number of Straight Lines to connect all the given Points
Given 2d integer array arr[][] containing N coordinates each of type {X, Y}, the task is to find the minimum number of straight lines required to connect all the points of the array. Examples: Input: arr[][] = {{1, 7}, {2, 6}, {3, 5}, {4, 4}, {5, 4}, {6, 3}, {7, 2}, {8, 1}}Output: 3Explanation: The diagram represents the input points and the minimu
8 min read
Number of triangles in a plane if no more than two points are collinear
Given n points in a plane and no more than two points are collinear, the task is to count the number of triangles in a given plane. Examples: Input : n = 3 Output : 1 Input : n = 4 Output : 4 Let there are n points in a plane and no three or more points are collinear then number of triangles in the given plane is given by [Tex]^{n}\textrm{C}_{3} =
4 min read
Program to find equation of a plane passing through 3 points
Given three points (x1, y1, z1), (x2, y2, z2), (x3, y3, z3). The task is to find the equation of the plane passing through these 3 points. Examples: Input: x1 = -1 y1 = w z1 = 1 x2 = 0 y2 = -3 z2 = 2 x3 = 1 y3 = 1 z3 = -4 Output: equation of plane is 26 x + 7 y + 9 z + 3 = 0.Input: x1 = 2, y1 = 1, z1 = -1, 1 x2 = 0, y2 = -2, z2 = 0 x3 = 1, y3 = -1,
10 min read
Article Tags :
Practice Tags :