Open In App

Minimum cost to connect all cities

Last Updated : 28 Feb, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

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:

  • Start from any random city (usually city 1).
  • Use a Min-Heap (Priority Queue) to always pick the cheapest edge.
  • Maintain a visited array to keep track of cities included in the MST.
  • Add edges to the MST until all cities are connected and return answer at last.
C++
#include <bits/stdc++.h>
using namespace std;

// Function to find the minimum cost to connect all the cities
int findMST(int n, vector<vector<int>>& 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<int>> 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<Edge> {
        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<Edge>> 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<Edge> {
        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<Edge>> adj = new List<List<Edge>>();
        for (int i = 0; i <= n; i++) adj.Add(new List<Edge>()); // 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));

Output
10
106



Next Article
Article Tags :
Practice Tags :

Similar Reads