Minimum cost to connect all cities (original) (raw)

Last Updated : 28 Feb, 2025

There are n cities and there are roads in between some of the cities. Somehow all the roads are damaged simultaneously. We have to repair the roads to connect the cities again. There is a fixed cost to repair a particular road.

Input is in the form of edges {u, v, w} where, u and v are city indices. w is the cost to rebuild the road between u and v. Print out the minimum cost to connect all the cities by repairing roads.

**Examples:

**Input: {{1, 2, 1}, {1, 3, 2}, {1, 4, 3}, {1, 5, 4},
{2, 3, 5}, {2, 5, 7}, {3, 4, 6}}
**Output: 10
**Explanation: Refer the fig...

citymap-2

Citymap with 5 cities and 7 damaged road

**Input : {{1, 2, 1}, {1, 3, 1}, {1, 4, 100},
{2, 3, 1}, {4, 5, 2}, {4, 6, 2}, {5, 6, 2}}
**Output : 106
**Explanation: Minimum cost to connect all the cities is 106

**Input: {{1,2,5},{2,4,2},{4,3,1},{1,3,7},{1,4,7},{3,,5,3}}
**Output: 11
**Explanation: Minimum cost to connect all the cities is 11

**[Approach] Using Prim's Algorithm - O(ElogV) Time and O(n) Space

We can solve this problem using **Prim's Algorithm, which finds the **Minimum Spanning Tree (MST) to connect all cities with the minimum repair cost.

**Steps-by-step approach:

#include <bits/stdc++.h> using namespace std;

// Function to find the minimum cost to connect all the cities int findMST(int n, vector<vector>& edges) { vector<vector<pair<int, int>>> adj(n + 1); // 1-based indexing

// Convert edge list to adjacency list (1-based indexing adjustment)
for (auto& edge : edges) {
    int u = edge[0], v = edge[1], w = edge[2];
    adj[u].push_back({w, v});
    adj[v].push_back({w, u});
}

// Min-Heap (Priority Queue) to store {weight, node}
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

vector<bool> inMST(n + 1, false); // To keep track of included nodes
pq.push({0, 1});  // Start from node **1** instead of 0
int mstCost = 0;  // Store MST Cost

while (!pq.empty()) {
    auto tmp = pq.top(); // Get the node with the smallest weight
    int w = tmp.first;
    int u = tmp.second;
    pq.pop();

    // If the node is already in MST, ignore it
    if (inMST[u]) continue;
    inMST[u] = true;
    mstCost += w; // Add weight to MST cost

    // Process all adjacent nodes
    for (auto& it : adj[u]) {
        
        int weight = it.first;
        int v = it.second;
        
        if (!inMST[v]) {
            pq.push({weight, v});
        }
    }
}

return mstCost;

}

// Driver function int main() { // Input: List of edges {u, v, weight} (1-based indexing) vector<vector> city1 = { {1, 2, 1}, {1, 3, 2}, {1, 4, 3}, {1, 5, 4}, {2, 3, 5}, {2, 5, 7}, {3, 4, 6} }; cout <<findMST(5, city1) << endl;

vector<vector<int>> city2 = {
    {1, 2, 1}, {1, 3, 1}, {1, 4, 100},
    {2, 3, 1}, {4, 5, 2}, {4, 6, 2}, {5, 6, 2}
};
cout <<findMST(6, city2) << endl;

return 0;

}

Java

import java.util.*;

class PrimMST { static class Edge implements Comparable { int node, weight; Edge(int node, int weight) { this.node = node; this.weight = weight; } public int compareTo(Edge other) { return this.weight - other.weight; } } // Function to find the minimum cost to connect all the cities public static int findMST(int n, int[][] edges) { List<List> adj = new ArrayList<>(); for (int i = 0; i <= n; i++) adj.add(new ArrayList<>()); // 1-based indexing

    // Convert edge list to adjacency list
    for (int[] edge : edges) {
        int u = edge[0], v = edge[1], w = edge[2];
        adj.get(u).add(new Edge(v, w));
        adj.get(v).add(new Edge(u, w));
    }

    PriorityQueue<Edge> pq = new PriorityQueue<>();
    boolean[] inMST = new boolean[n + 1]; // 1-based indexing
    pq.add(new Edge(1, 0)); // Start from node 1

    int mstCost = 0;
    while (!pq.isEmpty()) {
        Edge edge = pq.poll();
        int u = edge.node, weight = edge.weight;

        if (inMST[u]) continue;
        inMST[u] = true;
        mstCost += weight;

        for (Edge neighbor : adj.get(u)) {
            if (!inMST[neighbor.node]) {
                pq.add(neighbor);
            }
        }
    }
    return mstCost;
}

public static void main(String[] args) {
    int[][] city1 = {
        {1, 2, 1}, {1, 3, 2}, {1, 4, 3}, {1, 5, 4},
        {2, 3, 5}, {2, 5, 7}, {3, 4, 6}
    };
    System.out.println(findMST(5, city1));

    int [][] city2 = {
        {1, 2, 1}, {1, 3, 1}, {1, 4, 100},
        {2, 3, 1}, {4, 5, 2}, {4, 6, 2}, {5, 6, 2}
    };
    System.out.println(findMST(6, city2));
}

}

Python

import heapq

Function to find the minimum cost to connect all the cities

def findMST(n, edges): adj = [[] for _ in range(n + 1)] # 1-based indexing

# Convert edge list to adjacency list
for u, v, w in edges:
    adj[u].append((w, v))
    adj[v].append((w, u))

pq = [(0, 1)]  # (weight, node), start from node 1
inMST = [False] * (n + 1)  # 1-based indexing
mstCost = 0

while pq:
    w, u = heapq.heappop(pq)
    if inMST[u]:
        continue
    inMST[u] = True
    mstCost += w

    for weight, v in adj[u]:
        if not inMST[v]:
            heapq.heappush(pq, (weight, v))

return mstCost

Example usage with 1-based indexing

city1 = [ (1, 2, 1), (1, 3, 2), (1, 4, 3), (1, 5, 4), (2, 3, 5), (2, 5, 7), (3, 4, 6) ] print(findMST(5, city1))

city2 = [ (1, 2, 1), (1, 3, 1), (1, 4, 100), (2, 3, 1), (4, 5, 2), (4, 6, 2), (5, 6, 2) ] print(findMST(6, city2))

C#

using System; using System.Collections.Generic;

class PrimMST { class Edge : IComparable { public int Node, Weight; public Edge(int node, int weight) { Node = node; Weight = weight; } public int CompareTo(Edge other) { return Weight.CompareTo(other.Weight); } } // Function to find the minimum cost to connect all the cities static int FindMST(int n, List<int[]> edges) { List<List> adj = new List<List>(); for (int i = 0; i <= n; i++) adj.Add(new List()); // 1-based indexing

    // Convert edge list to adjacency list (1-based)
    foreach (var edge in edges) {
        int u = edge[0], v = edge[1], w = edge[2];
        adj[u].Add(new Edge(v, w));
        adj[v].Add(new Edge(u, w));
    }

    // Using SortedSet as a MinHeap because C# PriorityQueue doesn't sort correctly
    SortedSet<(int, int)> pq = new SortedSet<(int, int)>(); // (weight, node)
    bool[] inMST = new bool[n + 1]; // 1-based indexing
    pq.Add((0, 1)); // Start from node 1

    int mstCost = 0;

    while (pq.Count > 0) {
        var (weight, u) = pq.Min;
        pq.Remove(pq.Min); // Remove the smallest element

        if (inMST[u]) continue;
        inMST[u] = true;
        mstCost += weight;

        foreach (var neighbor in adj[u]) {
            if (!inMST[neighbor.Node]) {
                pq.Add((neighbor.Weight, neighbor.Node));
            }
        }
    }
    return mstCost;
}

static void Main() {
    List<int[]> city1 = new List<int[]> {
        new int[] {1, 2, 1}, new int[] {1, 3, 2}, new int[] {1, 4, 3}, new int[] {1, 5, 4},
        new int[] {2, 3, 5}, new int[] {2, 5, 7}, new int[] {3, 4, 6}
    };
    Console.WriteLine(FindMST(5, city1));

    List<int[]> city2 = new List<int[]> {
        new int[] {1, 2, 1}, new int[] {1, 3, 1}, new int[] {1, 4, 100},
        new int[] {2, 3, 1}, new int[] {4, 5, 2}, new int[] {4, 6, 2}, new int[] {5, 6, 2}
    };
    Console.WriteLine(FindMST(6, city2));
}

}

JavaScript

class MinHeap { constructor() { this.heap = []; }

push(item) {
    this.heap.push(item);
    this.heap.sort((a, b) => a[0] - b[0]); // Min-Heap sorting
}

pop() {
    return this.heap.shift(); // Extract min element
}

size() {
    return this.heap.length;
}

} // Function to find the minimum cost to connect all the cities function findMST(n, edges) { let adj = Array.from({ length: n + 1 }, () => []); // 1-based indexing

// Convert edge list to adjacency list (1-based)
edges.forEach(([u, v, w]) => {
    adj[u].push([w, v]);
    adj[v].push([w, u]);
});

let pq = new MinHeap();
let inMST = new Array(n + 1).fill(false); // 1-based indexing
pq.push([0, 1]); // Start from node 1
let mstCost = 0;

while (pq.size() > 0) {
    let [w, u] = pq.pop();

    if (inMST[u]) continue;
    inMST[u] = true;
    mstCost += w;

    for (let [weight, v] of adj[u]) {
        if (!inMST[v]) {
            pq.push([weight, v]);
        }
    }
}

return mstCost;

}

// Example Usage (1-based Indexing) let city1 = [ [1, 2, 1], [1, 3, 2], [1, 4, 3], [1, 5, 4], [2, 3, 5], [2, 5, 7], [3, 4, 6] ]; console.log(findMST(5, city1));

let city2 = [ [1, 2, 1], [1, 3, 1], [1, 4, 100], [2, 3, 1], [4, 5, 2], [4, 6, 2], [5, 6, 2] ]; console.log(findMST(6, city2));

`