Minimum Cost

  • If the number of roads is zero or cost of building a road is more than cost of building a library, then building libraries in each of the cities will result in minimum cost.
  • If the cost of building a library is less than cost of building a road, then building a single library and building roads to connected cities will result in minimum cost.

Clusters

There can be few set of cities that are not connected to each other and are clusters. Minimum cost is summation of minimum cost for all clusters.

Solution

  • Each city is a vertex and each road is an undirected edge in a graph.
  • DFS (Depth First Search) algorithm is used to traverse all cities in each cluster.
  • Number of roads in each cluster is one less than the number of cities traversed.
/* Solution to HackerRank: Roads and Libraries
 * URL: https://www.hackerrank.com/challenges/torque-and-development
 */

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int q = in.nextInt();
        for(int a0 = 0; a0 < q; a0++){
            int c = in.nextInt();
            int r = in.nextInt();
            long cl = in.nextLong();
            long cr = in.nextLong();
            
            Graph graph = new Graph(c);

            for(int a1 = 0; a1 < r; a1++){
                int city_1 = in.nextInt();
                int city_2 = in.nextInt();
                
                // start index from 0
                graph.addEdge(city_1-1,city_2-1);
            }
            
            // if number of roads is 0 or cost of building a library is less than or equal to cost of building a road
            // minimum cost will be building libraries in all the cities
            if(cl <= cr || r == 0){
                System.out.println(cl*c);
            }
            else{
                boolean[] visited = new boolean[c];
                long cost = 0;
                
                // there may be more than one unconnected cluster
                for(int i = 0; i < c; i++){
                    if(!visited[i]){
                        
                        //System.out.print("Cluster: ");
                        
                        // number of roads will be one less than the vertices traversed during DFS
                        int roads = graph.dfs(i, visited)-1;
                        
                        //System.out.println("");
                        //System.out.println("Roads: "+roads);
                        
                        // cost will be building all the roads in the cluster and a library
                        cost += roads*cr;
                        cost += cl;
                    }
                }            

                System.out.println(cost); 
            }            
        }
    }
}

class Graph{
    List<Integer>[] vertices;
    
    public Graph(int count){
        vertices = new ArrayList[count];
        
        for(int i = 0; i < count; i++){
            vertices[i] = new ArrayList<Integer>();
        }
    }
    
    public void addEdge(int source, int destination){
        vertices[source].add(destination);
        vertices[destination].add(source);
    }
    
    public int dfs(int source, boolean[] visited){
        visited[source] = true;
        int roads = 1;
        
        //System.out.print(source+" ");
        
        for(Integer vertex: vertices[source]){
            if(!visited[vertex]){
                roads += dfs(vertex, visited);
            }
        }
        
        return roads;
    }
}