Connect n ropes with minimum cost

23 Jun, 2022
There are given n ropes of different lengths, we need to connect these ropes into one rope. The cost to connect two ropes is equal to the sum of their lengths. We need to connect the ropes with minimum cost.
For example, if we are given 4 ropes of lengths 4, 3, 2, and 6. We can connect the ropes in the following ways. 
First, connect ropes of lengths 2 and 3. Now we have three ropes of lengths 4, 6, and 5. Now connect ropes of lengths 4 and 5. Now we have two ropes of lengths 6 and 9. Finally connect the two ropes and all ropes have connected.
First, connect ropes of lengths 2 and 3. Now we have three ropes of lengths 4, 6, and 5. 
Now connect ropes of lengths 4 and 5. Now we have two ropes of lengths 6 and 9. 
Finally connect the two ropes and all ropes have connected.
Total cost for connecting all ropes is 5 + 9 + 15 = 29. This is the optimized cost for connecting ropes. Other ways of connecting ropes would always have same or more cost. For example, if we connect 4 and 6 first (we get three strings of 3, 2, and 10), then connect 10 and 3 (we get two strings of 13 and 2). Finally, we connect 13 and 2. Total cost in this way is 10 + 13 + 15 = 38.
Solution: 
If we observe the above problem closely, we can notice that the lengths of the ropes which are picked first are included more than once in total cost. Therefore, the idea is to connect the smallest two ropes first and recur for the remaining ropes. This approach is similar to Huffman Coding. We put the smallest ropes down the tree so that they can be repeated multiple times rather than the longer ropes.
So it forms a structure like a tree:  
The sum contains sum of depth of each value. For array (2, 3, 4, 6) the sum is equal to 2 * 3 + 3 * 3 + 4 * 2 + 6 * 1 = 29 (According to the diagram). 
Algorithm:  
Create a min-heap and insert all lengths into the min-heap.Do following while the number of elements in min-heap is not one. Extract the minimum and second minimum from min-heapAdd the above two extracted values and insert the added value to the min-heap.Maintain a variable for total cost and keep incrementing it by the sum of extracted values.Return the value of this total cost.
Create a min-heap and insert all lengths into the min-heap.
Do following while the number of elements in min-heap is not one. Extract the minimum and second minimum from min-heapAdd the above two extracted values and insert the added value to the min-heap.Maintain a variable for total cost and keep incrementing it by the sum of extracted values.
Extract the minimum and second minimum from min-heapAdd the above two extracted values and insert the added value to the min-heap.Maintain a variable for total cost and keep incrementing it by the sum of extracted values.
Extract the minimum and second minimum from min-heap
Add the above two extracted values and insert the added value to the min-heap.
Maintain a variable for total cost and keep incrementing it by the sum of extracted values.
Return the value of this total cost.
Following is the implementation of the above algorithm.  
C++
Java
C#
// C++ program for connecting// n ropes with minimum cost#include <bits/stdc++.h> using namespace std; // A Min Heap: Collection of min heap nodesstruct MinHeap {    unsigned size; // Current size of min heap    unsigned capacity; // capacity of min heap    int* harr; // Array of minheap nodes}; // A utility function to create// a min-heap of a given capacitystruct MinHeap* createMinHeap(unsigned capacity){    struct MinHeap* minHeap = new MinHeap;    minHeap->size = 0; // current size is 0    minHeap->capacity = capacity;    minHeap->harr = new int[capacity];    return minHeap;} // A utility function to swap two min heap nodesvoid swapMinHeapNode(int* a, int* b){    int temp = *a;    *a = *b;    *b = temp;} // The standard minHeapify function.void minHeapify(struct MinHeap* minHeap, int idx){    int smallest = idx;    int left = 2 * idx + 1;    int right = 2 * idx + 2;     if (left < minHeap->size        && minHeap->harr[left] < minHeap->harr[smallest])        smallest = left;     if (right < minHeap->size        && minHeap->harr[right] < minHeap->harr[smallest])        smallest = right;     if (smallest != idx) {        swapMinHeapNode(&minHeap->harr[smallest], &minHeap->harr[idx]);        minHeapify(minHeap, smallest);    }} // A utility function to check// if size of heap is 1 or notint isSizeOne(struct MinHeap* minHeap){    return (minHeap->size == 1);} // A standard function to extract// minimum value node from heapint extractMin(struct MinHeap* minHeap){    int temp = minHeap->harr[0];    minHeap->harr[0] = minHeap->harr[minHeap->size - 1];    --minHeap->size;    minHeapify(minHeap, 0);    return temp;} // A utility function to insert// a new node to Min Heapvoid insertMinHeap(struct MinHeap* minHeap, int val){    ++minHeap->size;    int i = minHeap->size - 1;    while (i && (val < minHeap->harr[(i - 1) / 2])) {        minHeap->harr[i] = minHeap->harr[(i - 1) / 2];        i = (i - 1) / 2;    }    minHeap->harr[i] = val;} // A standard function to build min-heapvoid buildMinHeap(struct MinHeap* minHeap){    int n = minHeap->size - 1;    int i;    for (i = (n - 1) / 2; i >= 0; --i)        minHeapify(minHeap, i);} // Creates a min-heap of capacity// equal to size and inserts all values// from len[] in it. Initially, size// of min heap is equal to capacitystruct MinHeap* createAndBuildMinHeap(    int len[], int size){    struct MinHeap* minHeap = createMinHeap(size);    for (int i = 0; i < size; ++i)        minHeap->harr[i] = len[i];    minHeap->size = size;    buildMinHeap(minHeap);    return minHeap;} // The main function that returns// the minimum cost to connect n// ropes of lengths stored in len[0..n-1]int minCost(int len[], int n){    int cost = 0; // Initialize result     // Create a min heap of capacity    // equal to n and put all ropes in it    struct MinHeap* minHeap = createAndBuildMinHeap(len, n);     // Iterate while size of heap doesn't become 1    while (!isSizeOne(minHeap)) {        // Extract two minimum length        // ropes from min heap        int min = extractMin(minHeap);        int sec_min = extractMin(minHeap);         cost += (min + sec_min); // Update total cost         // Insert a new rope in min heap        // with length equal to sum        // of two extracted minimum lengths        insertMinHeap(minHeap, min + sec_min);    }     // Finally return total minimum    // cost for connecting all ropes    return cost;} // Driver program to test above functionsint main(){    int len[] = { 4, 3, 2, 6 };    int size = sizeof(len) / sizeof(len[0]);    cout << "Total cost for connecting ropes is "         << minCost(len, size);    return 0;}
// Java program to connect n// ropes with minimum cost // A class for Min Heapclass MinHeap {    int[] harr; // Array of elements in heap    int heap_size; // Current number of elements in min heap    int capacity; // maximum possible size of min heap     // Constructor: Builds a heap from    // a given array a[] of given size    public MinHeap(int a[], int size)    {        heap_size = size;        capacity = size;        harr = a;        int i = (heap_size - 1) / 2;        while (i >= 0) {            MinHeapify(i);            i--;        }    }     // A recursive method to heapify a subtree    // with the root at given index    // This method assumes that the subtrees    // are already heapified    void MinHeapify(int i)    {        int l = left(i);        int r = right(i);        int smallest = i;        if (l < heap_size && harr[l] < harr[i])            smallest = l;        if (r < heap_size && harr[r] < harr[smallest])            smallest = r;        if (smallest != i) {            swap(i, smallest);            MinHeapify(smallest);        }    }     int parent(int i) { return (i - 1) / 2; }     // to get index of left child of node at index i    int left(int i) { return (2 * i + 1); }     // to get index of right child of node at index i    int right(int i) { return (2 * i + 2); }     // Method to remove minimum element (or root) from min heap    int extractMin()    {        if (heap_size <= 0)            return Integer.MAX_VALUE;        if (heap_size == 1) {            heap_size--;            return harr[0];        }         // Store the minimum value, and remove it from heap        int root = harr[0];        harr[0] = harr[heap_size - 1];        heap_size--;        MinHeapify(0);         return root;    }     // Inserts a new key 'k'    void insertKey(int k)    {        if (heap_size == capacity) {            System.out.println("Overflow: Could not insertKey");            return;        }         // First insert the new key at the end        heap_size++;        int i = heap_size - 1;        harr[i] = k;         // Fix the min heap property if it is violated        while (i != 0 && harr[parent(i)] > harr[i]) {            swap(i, parent(i));            i = parent(i);        }    }     // A utility function to check    // if size of heap is 1 or not    boolean isSizeOne()    {        return (heap_size == 1);    }     // A utility function to swap two elements    void swap(int x, int y)    {        int temp = harr[x];        harr[x] = harr[y];        harr[y] = temp;    }     // The main function that returns the    // minimum cost to connect n ropes of    // lengths stored in len[0..n-1]    static int minCost(int len[], int n)    {        int cost = 0; // Initialize result         // Create a min heap of capacity equal        // to n and put all ropes in it        MinHeap minHeap = new MinHeap(len, n);         // Iterate while size of heap doesn't become 1        while (!minHeap.isSizeOne()) {            // Extract two minimum length ropes from min heap            int min = minHeap.extractMin();            int sec_min = minHeap.extractMin();             cost += (min + sec_min); // Update total cost             // Insert a new rope in min heap with length equal to sum            // of two extracted minimum lengths            minHeap.insertKey(min + sec_min);        }         // Finally return total minimum        // cost for connecting all ropes        return cost;    }     // Driver code    public static void main(String args[])    {        int len[] = { 4, 3, 2, 6 };        int size = len.length;         System.out.println("Total cost for connecting ropes is " + minCost(len, size));    }}; // This code is contributed by shubham96301
// C# program to connect n ropes with minimum costusing System; // A class for Min Heapclass MinHeap {    int[] harr; // Array of elements in heap    int heap_size; // Current number of elements in min heap    int capacity; // maximum possible size of min heap     // Constructor: Builds a heap from    // a given array a[] of given size    public MinHeap(int[] a, int size)    {        heap_size = size;        capacity = size;        harr = a;        int i = (heap_size - 1) / 2;        while (i >= 0) {            MinHeapify(i);            i--;        }    }     // A recursive method to heapify a subtree    // with the root at given index    // This method assumes that the subtrees    // are already heapified    void MinHeapify(int i)    {        int l = left(i);        int r = right(i);        int smallest = i;        if (l < heap_size && harr[l] < harr[i])            smallest = l;        if (r < heap_size && harr[r] < harr[smallest])            smallest = r;        if (smallest != i) {            swap(i, smallest);            MinHeapify(smallest);        }    }     int parent(int i) { return (i - 1) / 2; }     // to get index of left child of node at index i    int left(int i) { return (2 * i + 1); }     // to get index of right child of node at index i    int right(int i) { return (2 * i + 2); }     // Method to remove minimum element (or root) from min heap    int extractMin()    {        if (heap_size <= 0)            return int.MaxValue;        if (heap_size == 1) {            heap_size--;            return harr[0];        }         // Store the minimum value, and remove it from heap        int root = harr[0];        harr[0] = harr[heap_size - 1];        heap_size--;        MinHeapify(0);         return root;    }     // Inserts a new key 'k'    void insertKey(int k)    {        if (heap_size == capacity) {            Console.WriteLine("Overflow: Could not insertKey");            return;        }         // First insert the new key at the end        heap_size++;        int i = heap_size - 1;        harr[i] = k;         // Fix the min heap property if it is violated        while (i != 0 && harr[parent(i)] > harr[i]) {            swap(i, parent(i));            i = parent(i);        }    }     // A utility function to check    // if size of heap is 1 or not    Boolean isSizeOne()    {        return (heap_size == 1);    }     // A utility function to swap two elements    void swap(int x, int y)    {        int temp = harr[x];        harr[x] = harr[y];        harr[y] = temp;    }     // The main function that returns the    // minimum cost to connect n ropes of    // lengths stored in len[0..n-1]    static int minCost(int[] len, int n)    {        int cost = 0; // Initialize result         // Create a min heap of capacity equal        // to n and put all ropes in it        MinHeap minHeap = new MinHeap(len, n);         // Iterate while size of heap doesn't become 1        while (!minHeap.isSizeOne()) {            // Extract two minimum length ropes from min heap            int min = minHeap.extractMin();            int sec_min = minHeap.extractMin();             cost += (min + sec_min); // Update total cost             // Insert a new rope in min heap with length equal to sum            // of two extracted minimum lengths            minHeap.insertKey(min + sec_min);        }         // Finally return total minimum        // cost for connecting all ropes        return cost;    }     // Driver code    public static void Main(String[] args)    {        int[] len = { 4, 3, 2, 6 };        int size = len.Length;         Console.WriteLine("Total cost for connecting ropes is " + minCost(len, size));    }}; // This code is contributed by Arnab Kundu
Total cost for connecting ropes is 29
Complexity Analysis:  
Time Complexity: O(nLogn), assuming that we use a O(nLogn) sorting algorithm. Note that heap operations like insert and extract take O(Logn) time.
Auxiliary Complexity:O(n), The space required to store the values in min heap
Algorithmic Paradigm: Greedy Algorithm
A simple implementation with STL in C++:
This uses priority_queue available in STL. Thanks to Pango89 for providing the below code. The approach and algorithm remain the same. The min Heap is replaced by a priority Queue. 
C++
Java
Python3
C#
Javascript
#include <bits/stdc++.h> using namespace std; int minCost(int arr[], int n){    // Create a priority queue    // https:// www.geeksforgeeks.org/priority-queue-in-cpp-stl/    // By default 'less' is used which is for decreasing order    // and 'greater' is used for increasing order    priority_queue<int, vector<int>, greater<int> > pq(arr, arr + n);     // Initialize result    int res = 0;     // While size of priority queue is more than 1    while (pq.size() > 1) {        // Extract shortest two ropes from pq        int first = pq.top();        pq.pop();        int second = pq.top();        pq.pop();         // Connect the ropes: update result and        // insert the new rope to pq        res += first + second;        pq.push(first + second);    }     return res;} // Driver program to test above functionint main(){    int len[] = { 4, 3, 2, 6 };    int size = sizeof(len) / sizeof(len[0]);    cout << "Total cost for connecting ropes is " << minCost(len, size);    return 0;}
// Java program to connect n// ropes with minimum costimport java.util.*; class ConnectRopes {    static int minCost(int arr[], int n)    {        // Create a priority queue        PriorityQueue<Integer> pq = new PriorityQueue<Integer>();         // Adding items to the pQueue        for (int i = 0; i < n; i++) {            pq.add(arr[i]);        }         // Initialize result        int res = 0;         // While size of priority queue        // is more than 1        while (pq.size() > 1) {            // Extract shortest two ropes from pq            int first = pq.poll();            int second = pq.poll();             // Connect the ropes: update result            // and insert the new rope to pq            res += first + second;            pq.add(first + second);        }         return res;    }     // Driver program to test above function    public static void main(String args[])    {        int len[] = { 4, 3, 2, 6 };        int size = len.length;        System.out.println("Total cost for connecting"                           + " ropes is " + minCost(len, size));    }}// This code is contributed by yash_pec
# Python3 program to connect n# ropes with minimum costimport heapq def minCost(arr, n):         # Create a priority queue out of the    # given list    heapq.heapify(arr)         # Initialize result    res = 0         # While size of priority queue    # is more than 1    while(len(arr) > 1):                 # Extract shortest two ropes from arr        first = heapq.heappop(arr)        second = heapq.heappop(arr)                 #Connect the ropes: update result        # and insert the new rope to arr        res += first + second        heapq.heappush(arr, first + second)             return res # Driver codeif __name__ == '__main__':         lengths = [ 4, 3, 2, 6 ]    size = len(lengths)         print("Total cost for connecting ropes is " +          str(minCost(lengths, size))) # This code is contributed by shivampatel5
// C# program to connect n// ropes with minimum costusing System;using System.Collections.Generic;public class ConnectRopes{  static int minCost(int []arr, int n)  {    // Create a priority queue    List<int> pq = new List<int>();     // Adding items to the pQueue    for (int i = 0; i < n; i++)    {      pq.Add(arr[i]);    }     // Initialize result    int res = 0;     // While size of priority queue    // is more than 1    while (pq.Count > 1)    {      pq.Sort();       // Extract shortest two ropes from pq      int first = pq[0];      int second = pq[1];      pq.RemoveRange(0, 2);       // Connect the ropes: update result      // and insert the new rope to pq      res += first + second;      pq.Add(first + second);    }    return res;  }   // Driver program to test above function  public static void Main(String []args)  {    int []len = { 4, 3, 2, 6 };    int size = len.Length;    Console.WriteLine("Total cost for connecting"                      + " ropes is " + minCost(len, size));  }} // This code is contributed by Rajput-Ji
<script> // JavaScript program to connect n// ropes with minimum cost function minCost(arr,n){    // Create a priority queue        let pq = [];           // Adding items to the pQueue        for (let i = 0; i < n; i++) {            pq.push(arr[i]);        }                      pq.sort(function(a,b){return a-b;});                 // Initialize result        let res = 0;           // While size of priority queue        // is more than 1        while (pq.length > 1) {            // Extract shortest two ropes from pq            let first = pq.shift();            let second = pq.shift();               // Connect the ropes: update result            // and insert the new rope to pq            res += first + second;            pq.push(first + second);            pq.sort(function(a,b){return a-b;});        }           return res;} // Driver program to test above functionlet len = [4, 3, 2, 6];let size = len.length;document.write("Total cost for connecting"                           + " ropes is " + minCost(len, size)); // This code is contributed by avanitrachhadiya2155 </script>
Total cost for connecting ropes is 29
Complexity Analysis:
Time Complexity: O(nLogn), assuming that we use a O(nLogn) sorting algorithm. Note that heap operations like insert and extract take O(Logn) time.
Auxiliary Complexity: O(n). The space required to store the values in min heap
JAGRITIBANSAL
AbhijeetSrivastava
nobody_cares
andrew1234
shivampatel5
Rajput-Ji
avanitrachhadiya2155
simranarora5sos
pintusaini
anikakapoor
neerajgupta8524
hardikkoriintern
Amazon
Goldman Sachs
OYO Rooms
Greedy
Heap
Queue
Amazon
OYO Rooms
Goldman Sachs
Greedy
Queue
Heap
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.