Skip to content
thecscience
THECSICENCE

Learn everything about computer science

  • Home
  • Human values
  • NCERT Solutions
  • HackerRank solutions
    • HackerRank Algorithms problems solutions
    • HackerRank C solutions
    • HackerRank C++ solutions
    • HackerRank Java problems solutions
    • HackerRank Python problems solutions
thecscience
THECSICENCE

Learn everything about computer science

HackerRank Rust & Murderer Problem Solution

Yashwant Parihar, May 21, 2023May 21, 2023

In this post, we will solve HackerRank Rust & Murderer Problem Solution.

Detective Rust is investigating a homicide and he wants to chase down the murderer. The murderer knows he would definitely get caught if he takes the main roads for fleeing, so he uses the village roads (or side lanes) for running away from the crime scene.

Rust knows that the murderer will take village roads and he wants to chase him down. He is observing the city map, but it doesn’t show the village roads (or side lanes) on it and shows only the main roads.

The map of the city is a graph consisting N nodes (labeled 1 to N) where a specific given node S represents the current position of Rust and the rest of the nodes denote other places in the city, and an edge between two nodes is a main road between two places in the city. It can be suitably assumed that an edge that doesn’t exist/isn’t shown on the map is a village road (side lane). That means, there is a village road between two nodes a and b iff(if and only If) there is no city road between them.
In this problem, distance is calculated as number of village roads (side lanes) between any two places in the city.
Rust wants to calculate the shortest distance from his position (Node S) to all the other places in the city if he travels only using the village roads (side lanes).
Note: The graph/map of the city is ensured to be a sparse graph.
Input Format
The first line contains T, denoting the number of test cases. T testcases follow. First line of each test case has two integers N. denoting the number of cities in the map and M. denoting the number of roads in the map.
The next M lines each consist of two space-separated integers x and y denoting a main road between city a and city y. The last line has an integer S, denoting the current position of Rust.

Note

  • No nodes will have a road to itself.
  • There will not be multiple edges between any pair of nodes i.e. there is at most one undirected edge between them.
  • Graph is guaranteed to be sparse.
  • It is guranteed that there will be a path between any pair of nodes using the side lanes.

Output Format

For each of T test cases, print a single line consisting of N-1 space separated integers, denoting the shortest distances of the remaining N-1 places from Rust’s position (that is all distances, except the source node to itself) using the village roads/side lanes in ascending order based on vertex number.

Sample Input 0

2
4 3
1 2
2 3
1 4
1
4 2
1 2
2 3
2

Sample Output 0

3 1 2
2 2 1

Explanation 0

The graph in the first testcase can be shown as:

node is 1 (marked S).
The distance from 1 to 2 is 3. Path: 1 -> 3 -> 4 -> 2
The distance from 1 to 3 is 1. Path: 1 -> 3
The distance from 1 to 4 is 2. Path: 1 -> 3 -> 4

HackerRank Rust & Murderer Problem Solution
HackerRank Rust & Murderer Problem Solution

Rust & Murderer C Solution

#include <stdio.h>
#include <malloc.h>
#define MAX_NODES   (15*10000)
#define MAX_ROAD    (1000000)
#define PRINTF(s...)  
//printf(s)

typedef struct t_road {
    struct t_road *p_start_next;
    struct t_road *p_end_next;
    unsigned short start;
    unsigned short end;
}ROAD, *pROAD;

typedef struct t_node {
    pROAD p_road;
    unsigned long distance;
    unsigned long id:30;
    unsigned long in_working_set:1;
    unsigned long done:1;
}NODE;

typedef struct t_working_node {
    unsigned long node:31;
    unsigned long valid:1;
}WORKING_NODE;

typedef struct t_working_set {
    unsigned long max_valid_index;
    unsigned long valid_count;
    WORKING_NODE  working_nodes[MAX_NODES + 1];
}WORKING_SET;

NODE city_nodes[MAX_NODES + 1];
WORKING_SET working_set;

void add_to_working_set(NODE *pnodes, WORKING_SET *parrs, unsigned long curr_node, unsigned long dist)
{
    unsigned long index;
    PRINTF("[%s %i] node:%lu in_working_set:%i distance:%lu(%lu) count:%lu(%lu)\n",
        __FUNCTION__, __LINE__, curr_node, pnodes[curr_node].in_working_set, pnodes[curr_node].distance, dist, parrs->valid_count, parrs->max_valid_index);
    if(pnodes[curr_node].in_working_set) {
        if(pnodes[curr_node].distance > dist)
            pnodes[curr_node].distance = dist;
    } else {
        parrs->working_nodes[parrs->valid_count].node = curr_node;
        parrs->valid_count++;
        pnodes[curr_node].distance = dist;
        pnodes[curr_node].in_working_set = 1;
    }
}

unsigned long remove_smallest_from_working_set(NODE *pnodes, WORKING_SET *parrs)
{
    unsigned long min_node;

    if(parrs->valid_count == parrs->max_valid_index)
        return 0;

    min_node = parrs->working_nodes[parrs->max_valid_index].node;
    parrs->max_valid_index++;
    pnodes[min_node].done = 1;
    PRINTF("[%s %i] node:%lu count:%lu(%lu)\n",
        __FUNCTION__, __LINE__, min_node, parrs->valid_count, parrs->max_valid_index);
    return min_node;
}

int
main(int argc, char *argv[])
{
    unsigned long test_cases;
    unsigned long cities, roads;
    pROAD   p_roads = NULL, p_temp_road;
    unsigned long alloced_roads = 0;
    unsigned long count, index, start, end, curr_id, start_location, write_index, index_1;
    unsigned long city_node_index[MAX_NODES], city_node_count;
    scanf("%lu", &test_cases);
    for(count = 0; count < test_cases; count++) {
        scanf("%lu %lu", &cities, &roads);
        if(alloced_roads >= roads) {
        } else {
            if(p_roads)
                free(p_roads);
            p_roads = malloc(sizeof(ROAD) * roads);
            alloced_roads = roads;
        }
        memset(&city_nodes, 0x00, (cities + 1) * sizeof(NODE));
        memset(&working_set.working_nodes[0], 0x00, (cities + 1)*sizeof(WORKING_NODE));
        working_set.max_valid_index = 0;
        working_set.valid_count = 0;
        for(index = 0; index < roads; index++) {
            scanf("%lu %lu", &start, &end);
            p_roads[index].start = start;
            p_roads[index].end = end;

            p_roads[index].p_start_next = city_nodes[start].p_road;
            city_nodes[start].p_road = &p_roads[index];
            city_nodes[start].distance = 0xffffffff;

            p_roads[index].p_end_next = city_nodes[end].p_road;
            city_nodes[end].p_road = &p_roads[index];
            city_nodes[end].distance = 0xffffffff;
        }
        for(index = 0; index < cities; index++) {
            city_node_index[index] = index + 1;
        }
        city_node_count = cities;
        scanf("%lu", &start_location);
        start = start_location;
        end /* curr_value*/ = 0;
        add_to_working_set(city_nodes, &working_set, start, end);
        curr_id = 5; //any number
        while((start = remove_smallest_from_working_set(city_nodes, &working_set)) > 0) {
            /* from this node check where all we can reach (i.e. !via roads) */
            curr_id++;
            city_nodes[start].id = curr_id;
            city_nodes[start].done = 1;
            p_temp_road = city_nodes[start].p_road;
            while(p_temp_road) {
                if(p_temp_road->start == start) {
                    city_nodes[p_temp_road->end].id = curr_id;
                    p_temp_road = p_temp_road->p_start_next;
                } else {
                    //printf("should not be coming here \n");
                    city_nodes[p_temp_road->start].id = curr_id;
                    p_temp_road = p_temp_road->p_end_next;
                }
            }
            write_index = 0;
            for(index = 0; index < city_node_count; index++) {
                index_1 = city_node_index[index];
                if(city_nodes[index_1].in_working_set == 1)
                    continue;
                if(city_nodes[index_1].done)
                    continue;
                city_node_index[write_index] = index_1;
                write_index++;
                if(city_nodes[index_1].id == curr_id)
                    continue;
                add_to_working_set(city_nodes, &working_set, index_1, city_nodes[start].distance+1);
            }
            city_node_count = write_index;
        }
        for(index = 1; index <= cities; index++) {
            if(index == start_location)
                continue;
            printf("%lu ", city_nodes[index].distance);
        }
        printf("\n");
    }
}

Rust & Murderer C++ Solution

#include <unordered_set>
#include <vector>
#include <iostream>
#include <algorithm>
#include <queue>
#define INF 999999999
using namespace std;

struct node : unordered_set<int>
{
  int dist;
  node():dist(INF){}
};

int main() 
{ 
  int T;
  cin>>T;
  for(int t=0; t<T; t++)
  {
    unordered_set<int> tovisit;
    int N, M;
    cin>>N>>M;
    for(int i=1; i<=N; i++) tovisit.insert(i);
    
    node nodes[N+1];
    for(int i=0, a, b; i<M; i++)
    {
      cin>>a>>b;
      nodes[a].insert(b);
      nodes[b].insert(a);
    }
      
    queue<int> Q;
    int S;
    cin>>S;
    Q.push(S);
    nodes[S].dist = 0;
    tovisit.erase(S);
    while(!tovisit.empty())
    {
      int act = Q.front();
      Q.pop();
      vector<int> torem;
      for(auto a : tovisit)   
       if(nodes[act].find(a) == nodes[act].end())
        if(nodes[a].dist == INF)
        {
          nodes[a].dist = nodes[act].dist + 1;
          Q.push(a); 
          torem.push_back(a);
        }
      for(int i=0; i<torem.size(); i++)
       tovisit.erase(torem[i]);
    }
    
    for(int i=1; i<=N; i++)
     if(i != S)
      cout<<nodes[i].dist<<" ";
    cout<<"\n";
  }
  return 0;
}

Rust & Murderer C Sharp Solution

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Xml.Serialization.Configuration;

namespace HackerRanking
{
    [DebuggerDisplay("{Begin},{End} ({Weight})")]
    class Node : IComparable<Node>
    {
        public Node(params int[] wInts)
        {
            Begin = wInts[0];
            End = wInts[1];
            if(wInts.Length > 2)
                Weight = wInts[2];
        }

        public Node AddPath(BigInteger weight)
        {
            var node = new Node(Begin, End, Weight);
            return node;
        }

        public int Begin;
        public int End;
        public int Weight;

        public int CompareTo(Node other)
        {
            return -Weight.CompareTo(other.Weight);
        }

        public static Dictionary<int, List<Node>> constructGraph(int edgeCount, TextReader reader)
        {
            var graph = new Dictionary<int, List<Node>>(4 + edgeCount / 4);
            for (int i = 0; i < edgeCount; i++)
            {
                var tuple = reader.ReadLine().Trim().Split(' ')
                    .Select(int.Parse)
                    .ToArray();

                if (!graph.ContainsKey(tuple[0]))
                    graph[tuple[0]] = new List<Node>();
                graph[tuple[0]].Add(new Node(tuple));

                if (!graph.ContainsKey(tuple[1]))
                    graph[tuple[1]] = new List<Node>();
                graph[tuple[1]].Add(new Node(new int[] { tuple[1], tuple[0] }));
            }
            return graph;
        }
    }


    internal class SolutionRustAndMurderer
    {
        private static void Main(String[] args)
        {
            /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution */
            TextReader reader = null;
            try
            {
                reader = File.OpenText(@"c:\temp\input06-RustAndMurderer.txt");
                reader = new StringReader(@"2
4 3
1 2
2 3
1 4
1
4 2
1 2
2 3
2");

            }
            catch
            {
                reader = Console.In;
            }
            if (reader == null)
                return;


            var q = int.Parse(reader.ReadLine());
            
            for (int i = 0; i < q; i++)
            {
                var tuple = reader.ReadLine().Split(' ').Select(int.Parse).ToArray();
                var nodesCount = tuple[0];
                var edgeCount = tuple[1];
                var graph = Node.constructGraph(edgeCount, reader);
                var start = int.Parse(reader.ReadLine());
                var s = doCount(start, nodesCount, graph);
                //File.AppendAllText(@"c:\temp\o6.txt", s + '\n');
                Console.WriteLine(s);
            }
        }

        static string doCount(int start, int nodesCount, Dictionary<int, List<Node>> graph)
        {
            var res = new int[nodesCount+1];
            var seen = new Dictionary<int, bool>();
            if (!graph.ContainsKey(start))
            {
                return string.Join(" ", Enumerable.Range(1, nodesCount - 1)
                    .Select(j => 1));
            }

            var root = graph[start];
            var queue = new Queue<int>();
            var rootset = root.Select(nn => nn.End).ToDictionary(nn => nn, nn => true);
            var complement = new SortedSet<int>();

            var dist = 1;
            for (int i = 1; i <= nodesCount; i++)
            {
                if (i == start || rootset.ContainsKey(i))
                {
                    complement.Add(i);
                    continue;
                }
                res[i] = dist;
                queue.Enqueue(i);
            }

            while (queue.Count > 0)
            {
                var n = queue.Dequeue();
                if (n < 0)
                {
                    dist = -n;
                    continue;                    
                }

                List<Node> node = (graph.ContainsKey(n)) ? graph[n] : new List<Node>() {new Node(0, 0, 0)};
                queue.Enqueue(-dist - 1);
                var tmpqueue = new Queue<int>();
                foreach (var i in complement)
                //for (int i = 1; i <= nodesCount; i++)
                {
                    if (i == start || res[i] > 0)
                        continue;

                    if(node.Select(nn => nn.End).Any(e => e == i))
                        continue;
                    

                    res[i] = dist + 1;
                    tmpqueue.Enqueue(i);
                }
                while (tmpqueue.Count > 0)
                {
                    var i = tmpqueue.Dequeue();
                    queue.Enqueue(i);
                    complement.Remove(i);
                }
            }

            var sb = new StringBuilder();
            for (int i = 1; i < res.Length; i++)
            {
                if(i == start)
                    continue;
                sb.Append(res[i]).Append(" ");
            }
            return sb.ToString();
        }

    }
}

Rust & Murderer Java Solution

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 input = new Scanner(System.in);
        int T = input.nextInt();
        for(int t = 0; t < T; t++)
        {
            int N = input.nextInt();//Cities(nodes)
            int M = input.nextInt();//Main roads(edges)
            HashMap<Integer,HashSet<Integer>> cityMap = new HashMap<>();

            //Build city map of main roads
            for(int i = 0; i < M; i++)
            {
                int source = input.nextInt();
                int target = input.nextInt();
                if(cityMap.containsKey(source)) cityMap.get(source).add(target);
                else 
                {
                    HashSet<Integer> roads = new HashSet<>(); roads.add(target);
                    cityMap.put(source, roads);
                }
                if(cityMap.containsKey(target)) cityMap.get(target).add(source);
                else 
                {
                    HashSet<Integer> roads = new HashSet<>(); roads.add(source);
                    cityMap.put(target, roads);
                }
            }
            
            //Starting point of search
            int startingPoint = input.nextInt();
            
            //Perform a BFS by traversing non-edges
            int[] distances = BFS_Distance(startingPoint, cityMap, N);
            
            //Print output
            StringBuilder output = new StringBuilder("");
            for(int i = 0; i < distances.length; i++)
            {
                if(i+1 != startingPoint)
                    output.append(distances[i]+" ");
            }
            System.out.println(output);
        }
    }
    
    //Performs a BFS from starting point to all non-neighbors
    static int[] BFS_Distance(int root, HashMap<Integer,HashSet<Integer>> graph, int N)
    {
        int[] distances = new int[N];
        
        HashSet<Integer> notVisited = new HashSet<>();
        HashSet<Integer> visited = new HashSet<>();
        for(int i = 1; i <= N; i++) notVisited.add(i);
        
        Queue<Integer> queue = new LinkedList<>();
        
        queue.offer(root);
        notVisited.remove(root);
        distances[0] = 0;
        
        while(!queue.isEmpty())
        {
            int curr = queue.poll();
            HashSet<Integer> neighbors = graph.get(curr);
                
            for(int nv : notVisited)
            {
                if(neighbors == null || !neighbors.contains(nv))
                {
                    queue.offer(nv);
                    distances[nv-1] = distances[curr-1]+1;
                    visited.add(nv);
                } 
            }
            notVisited.removeAll(visited);
            visited = new HashSet<>();
        }
        return distances;
    }
}

Rust & Murderer JavaScript Solution

'use strict';

const fs = require('fs');

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(str => str.trim());

    main();
});

function readLine() {
    return inputString[currentLine++];
}

/*
 * Complete the rustMurdered function below.
 */
function rustMurderer(n, graph, s) {
    const d = Array(n + 1);
    const sv = new Set();
    for (let i = 1; i <= n; i++) {
        d[i] = Number.MAX_SAFE_INTEGER;
        sv.add(i);
    }

    const stack = [];
    stack.size = 0;

    push(stack, s);
    d[s] = 0;
    sv.delete(s);

    while (stack.size > 0) {
        const v = pop(stack);
        const edges = graph[v];

        for (let i of sv) {
            if (!edges[i] && d[i] > d[v]) {
                d[i] = d[v] + 1;
                push(stack, i);
                sv.delete(i);
            }
        }
    }

    return d.filter((v, i) => !(i === 0 || i === s));
}

function pop(stack) {
    return stack[--stack.size];
}

function push(stack, value) {
    stack[stack.size++] = value;
}

function main() {
    const ws = fs.createWriteStream(process.env.OUTPUT_PATH);

    const t = parseInt(readLine(), 10);

    for (let tItr = 0; tItr < t; tItr++) {
        const nm = readLine().split(' ');

        const n = parseInt(nm[0], 10);

        const m = parseInt(nm[1], 10);

        let graph = Array(n + 1);

        for (let i = 1; i <= n; i++) {
            graph[i] = {};
        }

        for (let roadsRowItr = 0; roadsRowItr < m; roadsRowItr++) {
            const edge = readLine().split(' ').map(roadsTemp => parseInt(roadsTemp, 10));

            graph[edge[0]][edge[1]] = true;
            graph[edge[1]][edge[0]] = true;
        }

        const s = parseInt(readLine(), 10);

        let result = rustMurderer(n, graph, s);

        ws.write(result.join(" ") + "\n");
    }

    ws.end();
}

Rust & Murderer Python Solution

tests = int(input())

for _ in range(tests):
    [n, e] = [int(i) for i in input().split(" ")]
    dists = [1] * n
    roads = {}
    for _ in range(e):
        [n1, n2] = [int(i) for i in input().split(" ")]
        if n1 not in roads:
            roads[n1] = set()
        if n2 not in roads:
            roads[n2] = set()
        roads[n1].add(n2)
        roads[n2].add(n1)
    start_loc = int(input())
    not_visited = roads[start_loc] if start_loc in roads else set()
    newly_visited = set()
    curr_dist = 2
    while len(not_visited) > 0:
        for i in not_visited:
            diff = not_visited | roads[i]
            if len(diff) < n:
                dists[i-1] = curr_dist
                newly_visited.add(i)
        not_visited = not_visited - newly_visited
        newly_visited = set()
        curr_dist += 1
    del dists[start_loc-1]
    print(" ".join(str(i) for i in dists))
c C# C++ HackerRank Solutions java javascript python CcppCSharpHackerrank Solutionsjavajavascriptpython

Post navigation

Previous post
Next post

Leave a Reply

You must be logged in to post a comment.

  • HackerRank Dynamic Array Problem Solution
  • HackerRank 2D Array – DS Problem Solution
  • Hackerrank Array – DS Problem Solution
  • Von Neumann and Harvard Machine Architecture
  • Development of Computers
©2025 THECSICENCE | WordPress Theme by SuperbThemes