Sort by

recency

|

68 Discussions

|

  • + 0 comments

    Java solution below. BFS can be used for single source shortest distances in unweighted graphs, which is what this is. Build an adjacency list for city roads (since this graph is sparse, we'd want to be looking for nonexistence of city roads rather than existance of village roads during BFS, for efficiency). Keep track of unvisited nodes with a set.

    static int[] rustMurderer(int n, int[][] roads, int s) {
            
            // Build Adjacency List
            List<Set<Integer>> cityRoads = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                cityRoads.add(new HashSet<>());
            }
            int numRoads = roads.length;
            for (int i = 0; i < numRoads; i++) {
                int vertex1 = roads[i][0];
                int vertex2 = roads[i][1];
                cityRoads.get(vertex1 - 1).add(vertex2 - 1);
                cityRoads.get(vertex2 - 1).add(vertex1 - 1);
            }
            
            // Initialization for BFS
            int[] result = new int[n];
            result[s-1] = -1; // Use -1 to Indicate Source
            
            // Add Immediate Neighbors of Source to Queue
            Queue<Integer> BFSqueue = new LinkedList<>();
            Set<Integer> unvisited = new HashSet<>();
            for (int i = 1; i <=n; i++) {
                if (i != s) {
                    if (!cityRoads.get(s-1).contains(i - 1)) {
                        //System.out.println("Source Neighbor Added =" + (i));
                        result[i - 1] = 1;
                        BFSqueue.add(i);
                    } else {
                        unvisited.add(i);
                    }
                }
            }
            
            // BFS for Shortest Dist
            int currentLevel = 1;
            while(!BFSqueue.isEmpty()) {
                int currentNode = BFSqueue.poll();
                
                // Not At Same Level as Before, Increment Level
                if (result[currentNode - 1] != currentLevel) {
                    ++currentLevel;
                }
                //Add Valid Neighbors to Queue if Not Already Visited
                Iterator<Integer> currentUnvisited = unvisited.iterator();
                while (currentUnvisited.hasNext()) {
                    int i = currentUnvisited.next();
                    if (!cityRoads.get(currentNode-1).contains(i-1)) { // Can Go To This Node
                        result[i - 1] = currentLevel + 1;
                        BFSqueue.add(i);
                        currentUnvisited.remove();
                    }
                }
            } 
            
            // Build Output Array and Return
            int[] output = new int[n-1];
            boolean passedS = false;
            for (int i = 0; i < n; i++) {
                if (result[i] == -1) {
                    passedS = true;
                    continue;
                }
                output[passedS ? i - 1 : i] = result[i];
            }
            return output;
        }
    
  • + 1 comment

    For Solving this question here is my submission: 1- Find the adjacency list of compliment of the graph (this will be representing the village roads) 2- Run he BFS with shortest distance

    This is the simplest method in which this problem can be solved

  • + 0 comments

    Here is my solution in java, javascript, python, C, C++, Csharp HackerRank Rust & Murderer Problem Solution

  • + 0 comments

    Here is the solution of Rust & Murderer Click here

  • + 1 comment
    vector<int> rustMurderer(int n, vector<vector<int>> roads, int s) {
        /*
         * Write your code here.
         */
        unordered_map<int, unordered_set<int>> graph;
        
        /* Represent an input as a graph based on unordered_... types for
           the maximum insertion/removal performance. */
        for (int i = 1; i <= n; ++i)
            graph[i] = unordered_set<int>{};
        for (const auto& edge : roads) {
            graph[edge[0]].insert(edge[1]);
            graph[edge[1]].insert(edge[0]);
        }
        
        /* A list (set) of the top nodes. A top node is a node that we are currently
           analyse paths from. The top nodes have always the minimum possible distance
           measured as required by the task. */
        unordered_set<int> tops;
    
        /* The resulting distances. This vector also includes an element for a node
           `s` which will be removed later. */
        vector<int> distances(n);
    
        int current_distance = 0;
        
        /* Kickstart the process from the given node */
        tops.insert(s);
        distances[s - 1] = current_distance++;
    
        while (!tops.empty()) {
            unordered_map<int, int> ntops_paths;
        
            /* On each iteration we remove nodes and edges of the graph that
               are already processed, thus each node and edge is effectively
               visited once. */
               
            /* Now find out how many direct (one step) paths are there from the
               current list of top nodes to all nodes of the remaining graph. */
    
            /* Start with listing all possible nodes. */
            for (const auto& kvp : graph)
                ntops_paths[kvp.first] = 0;
    
            /* As soon as the direct path found, increment the number of paths
               to the node. */
            for (const auto from : tops) {
                for (const auto to : graph[from]) {
                    ntops_paths[to]++;
                    graph[to].erase(from);  /* Erase backward edge. */
                }
                ntops_paths.erase(from);  /* Exclude top nodes from further analysis. */
                graph.erase(from);  /* Erase the visited node with all forward edges. */
            }
    
            /* Now construct a new list of top nodes based on the fact that each node
               that is unreachable from at least one of the current top nodes via a
               "main road" is reachable via "side road". Effectively it means that
               the path number calculated above is at least 1 less than the number of
               the current top nodes. */
            unordered_set<int> ntops;
            for (const auto& kvp : ntops_paths)
                if (kvp.second < tops.size())
                    ntops.insert(kvp.first);
            
            /* Populate distances for the new top nodes. */
            for (const auto top : ntops)
                distances[top - 1] = current_distance;
            ++current_distance;
            
            /* Replace the current list of top nodes with the new one. */
            tops = move(ntops);
        }
        
        distances.erase(distances.begin() + s - 1);
    
        return distances;
    }