Connect n ropes with minimum cost

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 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 following ways.
1) First connect ropes of lengths 2 and 3. Now we have three ropes of lengths 4, 6 and 5.
2) Now connect ropes of lengths 4 and 5. Now we have two ropes of lengths 6 and 9.
3) 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.



We strongly recommend that you click here and practice it, before moving on to the 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 smallest two ropes first and recur for remaining ropes. This approach is similar to Huffman Coding. We put smallest ropes down the tree so that they can be repeated multiple times rather than the longer ropes.

Following is complete algorithm for finding the minimum cost for connecting n ropes.
Let there be n ropes of lengths stored in an array len[0..n-1]
1) Create a min heap and insert all lengths into the min heap.
2) Do following while number of elements in min heap is not one.
……a) Extract the minimum and second minimum from min heap
……b) Add the above two extracted values and insert the added value to the min-heap.
……c) Maintain a variable for total cost and keep incrementing it by the sum of extracted values.
3) Return the value of this total cost.

Following is the implementation of above algorithm.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for connecting n ropes with minimum cost
#include <iostream>
  
using namespace std;
  
// A Min Heap:  Collection of min heap nodes
struct MinHeap {
    unsigned size; // Current size of min heap
    unsigned capacity; // capacity of min heap
    int* harr; // Attay of minheap nodes
};
  
// A utility function to create a min heap of given capacity
struct 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 nodes
void 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 not
int isSizeOne(struct MinHeap* minHeap)
{
    return (minHeap->size == 1);
}
  
// A standard function to extract minimum value node from heap
int 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 Heap
void 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 funvtion to build min heap
void 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 capacity
struct 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 functions
int 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to connect n ropes with minimum cost
  
// A class for Min Heap
class 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to connect n ropes with minimum cost 
using System;
  
// A class for Min Heap 
class 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

chevron_right


Output:



Total cost for connecting ropes is 29

Time Complexity: Time complexity of the algorithm is O(nLogn) assuming that we use a O(nLogn) sorting algorithm. Note that heap operations like insert and extract take O(Logn) time.

Algorithmic Paradigm: Greedy Algorithm



A simple implementation with STL in C++
Following is a simple implementation that uses priority_queue available in STL. Thanks to Pango89 for providing below code.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

#include <iostream>
#include <queue>
  
using namespace std;
  
int minCost(int arr[], int n)
{
    // Create a priority queue ( http:// www.cplusplus.com/reference/queue/priority_queue/ )
    // 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 function
int 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to connect n
// ropes with minimum cost
import 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

chevron_right



Output:

Total cost for connecting ropes is 29

This article is compiled by Abhishek. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above



My Personal Notes arrow_drop_up