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 Journey Scheduling Problem Solution

Yashwant Parihar, May 21, 2023May 28, 2024

In this post, we will solve HackerRank Journey Scheduling Problem Solution.

Fedya is a seasoned traveller and is planning his trip to Treeland. Treeland is a country with an ancient road system which is in the form of a tree structure. N cities of Treeland are numbered by N positive integers: 1, 2, 3,…, N.
Fedya has not yet decided the starting point (city) of his journey and the cities he will visit. But there are a few things you know about Fedya’s trip:

  • Fedya is fond of travelling to great distances. So if he is currently located in city V. his destination will be a city which is most distant from city V.
  • There might be more than 1 such cities. In that case, Fedya will choose a city that was already visited as less times as possible in this journey.
  • There still might be more than 1 such cities. In that case, Fedya will go to the city with the smallest number.

Fedya has prepared a list of M possible journeys. Each one is characterized by two integers >the starting city V and the total number of cities to be visited, K. For each of them, he is keen to know the total distance travelled by him.

Input Format
The first line of input will contain two space separated integers N and M-the number of cities and the number of possible journeys.
Then, there will be (N-1) lines, each of them will contain two space separated integers
XY, denoting the bi-directional road between the cities with numbers X and Y with the unitary length.
Then there will be M lines, each of them will have two space separated Integers V and K. denoting a journey.

Output Format

For each journey, output the travelled distance on a separate line.

Sample Input

8 7
2 1
3 2
4 2
5 1
6 1
7 1
8 7
4 6
3 4
6 3
7 6
4 6
7 1
2 6

Sample Output

24
16
11
23
24
3
23

Explanation

The tree in question is given in the picture below.

  • 4 6 indicates that Fedya starts at 4. Now we see that the most distant city from 4 is 8. Fedya now travels to city 8. From 8, the most distance cities are [4, 3]. As 4 is already visited, he chooses to visit city 3. From city 3, he revisits city 8 and so on. The cities in the order of visit is 4 – > 8 -> 3 -> 8 -> 4 -> 8 -> 3 which sums to 24. Hence, the answer.
  • 6 3 indicates that Fedya starts at city 6. From 6, the most distant cities are [3,4,8]. In this leg of the journey, no city is visited and hence Fedya chooses to visit the city with the smallest number 3. From 3, he visits 8 and then he ends his trip at city 4 which sums to 3 + 4 + 4 = 11. Hence, the answer.
HackerRank Journey Scheduling Problem Solution
HackerRank Journey Scheduling Problem Solution

Journey Scheduling C Solution

        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        typedef struct _node{
          int x;
          int w;
          struct _node *next;
        } lnode;
        void insert_edge(int x,int y,int w);
        void dfs1(int x);
void dfs2(int x,int y);
int max(int x,int y);
        int h[100000],sh[100000],l[100000],u[100000],trace[100000];
        lnode *table[100000]={0};
         
        int main(){
          int N,M,x,y,i;
            scanf("%d%d",&N,&M);
            for(i=0;i<N-1;i++){
              scanf("%d%d",&x,&y);
              insert_edge(x-1,y-1,1);
            }
            memset(trace,0,sizeof(trace));
            dfs1(0);
            memset(trace,0,sizeof(trace));
            dfs2(0,-1);
            for(i=0;i<M;i++){
              scanf("%d%d",&x,&y);
              printf("%lld\n",max(h[x-1],u[x-1])+(y-1)*(long long)l[0]);
            }
          return 0;
        }
        void insert_edge(int x,int y,int w){
          lnode *t=malloc(sizeof(lnode));
          t->x=y;
          t->w=w;
          t->next=table[x];
          table[x]=t;
          t=malloc(sizeof(lnode));
          t->x=x;
          t->w=w;
          t->next=table[y];
          table[y]=t;
          return;
        }
        void dfs1(int x){
          lnode *p;
          trace[x]=1;
          h[x]=sh[x]=l[x]=0;
          for(p=table[x];p;p=p->next)
            if(!trace[p->x]){
              dfs1(p->x);
              if(h[p->x]+p->w>=h[x]){
                sh[x]=h[x];
                h[x]=h[p->x]+p->w;
              }
              else if(h[p->x]+p->w>sh[x])
                sh[x]=h[p->x]+p->w;
              if(l[p->x]>l[x])
                l[x]=l[p->x];
            }
          if(h[x]+sh[x]>l[x])
            l[x]=h[x]+sh[x];
          return;
        }
        void dfs2(int x,int y){
          lnode *p;
          trace[x]=1;
if(y==-1)
u[x]=0;
else
if(h[y]==h[x]+1)
u[x]=max(u[y]+1,sh[y]+1);
else
u[x]=max(u[y]+1,h[y]+1);
          for(p=table[x];p;p=p->next)
            if(!trace[p->x])
              dfs2(p->x,x);
          return;
        }
int max(int x,int y){
  return (x>y)?x:y;
}

Journey Scheduling C++ Solution

#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;

typedef long long ll;
#define REP(i, n) for (int i = 0; i < (n); i++)
#define pb push_back

int ri()
{
  int x;
  scanf("%d", &x);
  return x;
}

const int N = 100000;
vector<int> e[N];
int s[N], ss[N], far[N];

void dfs(int u, int p)
{
  for (int v: e[u])
    if (v != p) {
      dfs(v, u);
      if (s[v]+1 > ss[u]) {
        ss[u] = s[v]+1;
        if (ss[u] > s[u])
          swap(ss[u], s[u]);
      }
    }
}

void dfs2(int u, int p, int up)
{
  far[u] = max(s[u], up);
  for (int v: e[u])
    if (v != p)
      dfs2(v, u, max(s[v]+1 == s[u] ? ss[u] : s[u], up) + 1);
}

int main()
{
  int n = ri(), m = ri();
  REP(i, n-1) {
    int u = ri()-1, v = ri()-1;
    e[u].pb(v);
    e[v].pb(u);
  }
  dfs(0, -1);
  dfs2(0, -1, 0);
  ll diameter = *max_element(far, far+n);
  while (m--) {
    int x = ri()-1, y = ri();
    printf("%lld\n", (y-1)*diameter+far[x]);
  }
}

Journey Scheduling C Sharp Solution

using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.Text;
using System;

class Result
{

    /*
     * Complete the 'journeyScheduling' function below.
     *
     * The function is expected to return an INTEGER_ARRAY.
     * The function accepts following parameters:
     *  1. INTEGER n
     *  2. 2D_INTEGER_ARRAY roads
     *  3. 2D_INTEGER_ARRAY journeys
     */

    class LCA
    {
        private int[] _height;
        private List<int> _euler;
        private int[] _first;
        private int[] _segtree;
        private bool[] _visited;
        private int n;
        private int _diameter;
        private int _d1;
        private int _d2;


        public LCA(List<int>[] adj, int root = 0)
        {
            n = adj.Length;
            _height = new int[n];
            _first = new int[n];
            _euler = new List<int>(n*2);
            _visited = new bool[n];
            _diameter = 0;
            _d1 = root;
            
            DfsEuler(adj, root);
            _visited = new bool[n];
            _d2 = _d1;
            _diameter = 0;
            DfsD2(adj, _d1);

            int m = _euler.Count;
            _segtree = new int[m*4];
            Build(1, 0, m - 1);
        }

        private void DfsEuler(List<int>[] adj, int node, int h = 0)
        {
            _visited[node] = true;
            _height[node] = h;
            _first[node] = _euler.Count;
            _euler.Add(node);
            if (h > _diameter)
            {
                _d1 = node;
                _diameter = h;
            }
            foreach (var to in adj[node])
            {
                if (!_visited[to])
                {
                    DfsEuler(adj, to, h+1);
                    _euler.Add(node);
                }
            }
        }
        private void DfsD2(List<int>[] adj, int node, int h = 0)
        {
            _visited[node] = true;
            if (h > _diameter)
            {
                _d2 = node;
                _diameter = h;
            }
            foreach (var to in adj[node])
            {
                if (!_visited[to])
                {
                    DfsD2(adj, to, h+1);
                }
            }
        }
        private void Build(int node, int b, int e)
        {
            if (b == e)
            {
                _segtree[node] = _euler[b];
            }
            else
            {
                var mid = (b + e) / 2;
                Build(node * 2, b, mid);
                Build(node*2+1, mid+1, e);
                int l = _segtree[node * 2];
                int r = _segtree[node * 2 + 1];
                _segtree[node] = (_height[l] < _height[r]) ? l : r;
            }
        }

        private int Query(int node, int b, int e, int L, int R)
        {
            if (b > R || e < L) return -1;
            if (b >= L && e <= R)
                return _segtree[node];
            int mid = (b + e) / 2;
            int left = Query(node * 2, b, mid, L, R);
            int right = Query(node * 2 + 1, mid + 1, e, L, R);
            if (left == -1) return right;
            if (right == -1) return left;
            return _height[left] < _height[right] ? left : right;
        }

        int Lca(int u, int v)
        {
            int left = _first[u];
            int right = _first[v];
            if (left > right)
            {
                var val = left;
                left = right;
                right = val;
            }

            return Query(1, 0, _euler.Count - 1, left, right);
            
        }

        public int Distance(int u, int v)
        {
            var lca = Lca(u, v);
            return _height[u] + _height[v] - 2 * _height[lca];
        }

        public int DistanceToDiameter(int node)
        {
            return Math.Max(Distance(node, _d1), Distance(node, _d2));
        }

        public int Diameter => _diameter;

    }

    private static (int, int) FarthestNode(Dictionary<int, List<int>> al, int node)
    {
        var s = new Stack<(int,int, int)>();//node, distance, parentNode
        var max = (node, 0);
        s.Push((node, 0, node));
        while (s.Count > 0)
        {
            var cnode = s.Pop();
            var children = al[cnode.Item1].Where(n => n != cnode.Item3)
                .Select(n => (n, cnode.Item2 + 1, cnode.Item1)).ToList();
            if(children.Count>0 && children[0].Item2>max.Item2)
            {
                max = (children[0].Item1, children[0].Item2);
            }

            foreach (var child in children)
            {
                s.Push(child);
            }
            
        }
        return max;
    }

    public static List<long> journeyScheduling(int n, List<List<int>> roads, List<List<int>> journeys)
    {
        var adj = new List<int>[n];
        var nodeToBorder = new Dictionary<int, int>();

        foreach (var road in roads)
        {
            var from = road[0]-1;
            var to = road[1]-1;
            if (adj[from]!=null)
            {
                adj[from].Add(to);
            }
            else
            {
                adj[from] = new List<int> {to};
            }

            if (adj[to]!=null)
            {
                adj[to].Add(from);
            }
            else
            {
                adj[to] = new List<int> {from};
            }
        }

        //var r = new Random(1978).Next(n);

        var lca = new LCA(adj);
        

        var results = journeys.Select(joureney =>
        {
            if (nodeToBorder.ContainsKey(joureney[0]))
            {
                return (long)nodeToBorder[joureney[0]] + (long)(joureney[1] - 1) * lca.Diameter;
            }

            var toBorder = lca.DistanceToDiameter(joureney[0] - 1);
            
            nodeToBorder[joureney[0]] = toBorder;
            
            return (long)toBorder + (long)(joureney[1] - 1) * lca.Diameter;
        }).ToList();
        return results;
    }

}

class Solution
{
    public static void Main(string[] args)
    {
        TextWriter textWriter = new StreamWriter(@System.Environment.GetEnvironmentVariable("OUTPUT_PATH"), true);

        string[] firstMultipleInput = Console.ReadLine().TrimEnd().Split(' ');

        int n = Convert.ToInt32(firstMultipleInput[0]);

        int m = Convert.ToInt32(firstMultipleInput[1]);

        List<List<int>> roads = new List<List<int>>();

        for (int i = 0; i < n - 1; i++)
        {
            roads.Add(Console.ReadLine().TrimEnd().Split(' ').ToList().Select(roadsTemp => Convert.ToInt32(roadsTemp)).ToList());
        }

        List<List<int>> journeys = new List<List<int>>();

        for (int i = 0; i < m; i++)
        {
            journeys.Add(Console.ReadLine().TrimEnd().Split(' ').ToList().Select(journeysTemp => Convert.ToInt32(journeysTemp)).ToList());
        }

        List<long> result = Result.journeyScheduling(n, roads, journeys);

        textWriter.WriteLine(String.Join("\n", result));

        textWriter.Flush();
        textWriter.Close();
    }
}

Journey Scheduling Java Solution

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

public class Solution {
    private static class Node {
        final int index;
        final Set<Node> neighbors = new HashSet<>();

        Node(int index) {
            this.index = index;
        }
    }

    /*
     * Complete the journeyScheduling function below.
     */
    static long[] journeyScheduling(int n, int[][] roads, int[][] journeys) {
        Node[] nodes = new Node[n];
        for (int i = 0; i < n; i++) {
            nodes[i] = new Node(i);
        }
        for (int[] road : roads) {
            nodes[road[0] - 1].neighbors.add(nodes[road[1] - 1]);
            nodes[road[1] - 1].neighbors.add(nodes[road[0] - 1]);
        }

        Node start = findEnd(nodes[0]);
        Node end = findEnd(start);
        List<Node> diameterPath = findPath(start, end);
        int diameter = diameterPath.size() - 1;
        int[] distances = new int[n];
        if ((diameter & 1) == 0) {
            maxDistances(diameterPath.get(diameter/2), null, diameter/2, distances);
        } else {
            maxDistances(diameterPath.get(diameter/2), diameterPath.get(diameter/2 + 1), diameter/2 + 1, distances);
            maxDistances(diameterPath.get(diameter/2 + 1), diameterPath.get(diameter/2), diameter/2 + 1, distances);
        }
//        System.out.println(String.format("Diameter: %d, distances: %s", diameter, Arrays.toString(distances)));

        long[] results = new long[journeys.length];
        for (int i = 0; i < journeys.length; i++) {
            results[i] = distances[journeys[i][0] - 1] + ((long) diameter)*(journeys[i][1] - 1);
        }
        return results;
    }

    private static class State {
        final Node cur;
        final Node prev;
        final Iterator<Node> children;
        final int distance;

        State(Node cur, Node prev, int distance) {
            this.cur = cur;
            this.prev = prev;
            this.children = cur.neighbors.iterator();
            this.distance = distance;
        }
    }

    private static Node findEnd(Node cur) {
        Node end = cur;
        int maxDistance = -1;
        Deque<State> stack = new ArrayDeque<>();
        stack.addFirst(new State(cur, null, 0));
        while (!stack.isEmpty()) {
            State state = stack.peekFirst();
            if (state.children.hasNext()) {
                Node child = state.children.next();
                if (child == state.prev) {
                    // Do nothing
                } else if (child.neighbors.size() == 1) {
                    if (state.distance > maxDistance) {
                        maxDistance = state.distance;
                        end = child;
                    }
                } else {
                    stack.addFirst(new State(child, state.cur, state.distance + 1));
                }
            } else {
                stack.removeFirst();
            }
        }
        return end;
    }

    private static List<Node> findPath(Node cur, Node goal) {
        Deque<State> stack = new ArrayDeque<>();
        stack.addFirst(new State(cur, null, 0));
        while (stack.peekFirst().cur != goal) {
            State state = stack.peekFirst();
            if (state.children.hasNext()) {
                Node child = state.children.next();
                if (child != state.prev) {
                    stack.addFirst(new State(child, state.cur, 0));
                }
            } else {
                stack.removeFirst();
            }
        }

        List<Node> path = new ArrayList<>();
        while (!stack.isEmpty()) {
            path.add(stack.removeFirst().cur);
        }
        return path;
    }

    private static void maxDistances(Node cur, Node prev, int distance, int[] distances) {
        distances[cur.index] = distance;
        Deque<State> stack = new ArrayDeque<>();
        stack.addFirst(new State(cur, prev, distance));
        while (!stack.isEmpty()) {
            State state = stack.peekFirst();
            if (state.children.hasNext()) {
                Node child = state.children.next();
                if (child != state.prev) {
                    distances[child.index] = state.distance + 1;
                    stack.addFirst(new State(child, state.cur, state.distance + 1));
                }
            } else {
                stack.removeFirst();
            }
        }
    }

    private static final Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) throws IOException {
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));

        String[] nm = scanner.nextLine().split(" ");
        scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])*");

        int n = Integer.parseInt(nm[0]);

        int m = Integer.parseInt(nm[1]);

        int[][] roads = new int[n-1][2];

        for (int roadsRowItr = 0; roadsRowItr < n-1; roadsRowItr++) {
            String[] roadsRowItems = scanner.nextLine().split(" ");
            scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])*");

            for (int roadsColumnItr = 0; roadsColumnItr < 2; roadsColumnItr++) {
                int roadsItem = Integer.parseInt(roadsRowItems[roadsColumnItr]);
                roads[roadsRowItr][roadsColumnItr] = roadsItem;
            }
        }

        int[][] journeys = new int[m][2];

        for (int journeysRowItr = 0; journeysRowItr < m; journeysRowItr++) {
            String[] journeysRowItems = scanner.nextLine().split(" ");
            scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])*");

            for (int journeysColumnItr = 0; journeysColumnItr < 2; journeysColumnItr++) {
                int journeysItem = Integer.parseInt(journeysRowItems[journeysColumnItr]);
                journeys[journeysRowItr][journeysColumnItr] = journeysItem;
            }
        }

        long[] result;
//        try {
            result = journeyScheduling(n, roads, journeys);
/*        } catch (StackOverflowError e) {
            result = new long[1];
        }*/

        for (int resultItr = 0; resultItr < result.length; resultItr++) {
            bufferedWriter.write(String.valueOf(result[resultItr]));

            if (resultItr != result.length - 1) {
                bufferedWriter.write("\n");
            }
        }

        bufferedWriter.newLine();

        bufferedWriter.close();

        scanner.close();
    }
}

Journey Scheduling JavaScript Solution

function processData(input) {
    
    var inputValues=input.replace(/\n/g," ").split(" ");

    var N = parseInt(inputValues[0]);   //Number of Cities
    var M = parseInt(inputValues[1]);   //Number of possible journeys
    
    //bi-directional road between the cities with numbers X and Y
    var X = [];
    var Y = [];
    for (var i=0;i<N-1;i++) {
        X[i] = parseInt(inputValues[i*2+2]);
        Y[i] = parseInt(inputValues[i*2+3]);
    }
    
    //starting city V and the total number of cities to be visited K 
    var V = [];
    var K = [];
    for (var j=0;j<M;j++) {
        V[j] = parseInt(inputValues[j*2+N*2]);
        K[j] = parseInt(inputValues[j*2+N*2+1]);
    }

    //Convert edge list to adjacency list
    var graph = edgeToAdjList(X,Y);
    
    var singleNodes = 0;
    for (var key in graph) {
        if (graph.hasOwnProperty(key)) {
            if (graph[key].adjNodes.length == 1)       
                 singleNodes += 1;  
        }
    } 
    
    var alternativeMethod = false;    
    
    if(singleNodes/N > 0.9)    
        alternativeMethod = true;   
    
    if(alternativeMethod) {
        var distances = {};
        var initialNode = 1;
        
        var diameter = treeDiameter(graph, initialNode, 0, initialNode, distances, initialNode);
            
        var edge1 = initialNode;
        for (var key in distances[initialNode]) {
            if (distances[initialNode].hasOwnProperty(key)) {
                if (distances[initialNode][key]>distances[initialNode][edge1])       
                    edge1 = key;  
            }
        }     
        
        treeDiameter(graph, edge1, 0, edge1, distances, edge1);
        
        var edge2=edge1;
        for (var key in distances[edge1]) {
            if (distances[edge1].hasOwnProperty(key)) {
                if (distances[edge1][key]>distances[edge1][edge2])       
                    edge2 = key;  
            }
        }  
        
        treeDiameter(graph, edge2, 0, edge2, distances, edge1);
    

    
        //Calculate trip distances
        for(i=0;i<M;i++) {
            //console.log("Start of trip...");
            var initialCity = V[i];      //City of departure
            var tripsPending = K[i];     //Number of trips
            var totalDistance = 0;       //Distance accumulated during total trip
            
            
            var firstTripDistance = Math.max(distances[edge1][initialCity],distances[edge2][initialCity]);
    
            
            totalDistance = firstTripDistance + (diameter-1)*(tripsPending-1);
    
            
            console.log(totalDistance);
        }
    }
    else {
        var edgeDistances = {};
         
        //var edges = findTreeEdges(graph,edgeDistances);
        //var diameter = edgeDistances[edges[0]].maxDistance;
        
        var edges = findTreeDistances(graph,edgeDistances);
        
        var diameter = edgeDistances[edges[0]].maxDistance;      
        
        //Calculate trip distances
        for(i=0;i<M;i++) {
            //console.log("Start of trip...");
            var initialCity = V[i];      //City of departure
            var tripsPending = K[i];     //Number of trips
            var totalDistance = 0;       //Distance accumulated during total trip
            
            
            var firstTripDistance = 0;
            for(var j=0;j<edges.length;j++) {
                if(edgeDistances[edges[j]][initialCity]>firstTripDistance) {
                    firstTripDistance = edgeDistances[edges[j]][initialCity];
                }
            }
            
            totalDistance = firstTripDistance + diameter*(tripsPending-1);
    
            
            console.log(totalDistance);
            
        }        
    }
   

} 

process.stdin.resume();
process.stdin.setEncoding("ascii");
_input = "";
process.stdin.on("data", function (input) {
    _input += input;
});

process.stdin.on("end", function () {
   processData(_input);
});




function edgeToAdjList(X,Y) {
    var graph = {};
    
    //Loop through the edges list
    for (var i=0;i<X.length;i++) {
        //Check for X if node exists in graph, otherwise create it
        if (graph[X[i]]) {
            graph[X[i]].adjNodes.push(Y[i]);
        } else {
           graph[X[i]] = {}; 
           graph[X[i]].adjNodes = [Y[i]];
        }
        //Check for Y if node exists in graph, otherwise create it        
        if (graph[Y[i]]) {
            graph[Y[i]].adjNodes.push(X[i]);
        } else {
            graph[Y[i]] = {};             
            graph[Y[i]].adjNodes = [X[i]];
        }
    }
    return graph;   
}     



function bfs(adjlist, root) { 

    //Add distance and parent objects to every entry in the adjacency list
    for (var key in adjlist) {
        if (adjlist.hasOwnProperty(key)) {
            adjlist[key].distance = Infinity;       
            adjlist[key].parent = null;  
        }
    }    
    
    var Q = [];      
    
    adjlist[root].distance = 0;
    Q.push(adjlist[root]);
    
    //Calculate distances for every node in the graph versus the root node
    while(Q.length) {
        var current = Q.shift();
        for (var i=0;i<current.adjNodes.length;i++) {
            var n = adjlist[current.adjNodes[i]];
            if (!isFinite(n.distance)) {
                n.distance = current.distance + 1;
                n.parent = current;
                Q.push(n);
            }    
        }
      
        
    }  
    
    //Loop through the graph to find the nodes with further distance
    var furthestNodes = [];
    var maxDistance = 0;
    var dist = {};
    for (var key in adjlist) {
        if (adjlist.hasOwnProperty(key)) {
            dist[key] = adjlist[key].distance
            if (adjlist[key].distance > maxDistance) {
                maxDistance = adjlist[key].distance;
                furthestNodes = [key];              
            }
            else if (adjlist[key].distance == maxDistance) {
                furthestNodes.push(key);
            }
        }
    } 
    
    //Delete parent and distance properties
    for (var key in adjlist) {
        if (adjlist.hasOwnProperty(key)) {
            delete adjlist[key].distance;       
            delete adjlist[key].parent;
        }
    }  
    
    dist["furthestNodes"] = furthestNodes;
    dist["maxDistance"] = maxDistance;
        
    return dist;

};


function findTreeEdges(graph, distances) {
    
    var edges = [];
    var startingNode = 1;   //Assign node 1 as initial node
    
    //Calculate furthest edges from Node 1 as starting.point
    var initial = bfs(graph,startingNode);   
    
    var startingEdges = initial.furthestNodes   //Initial edges
    
    var E = [];      

    for(var i=0;i<Math.min(startingEdges.length,1);i++) {
        E.push(startingEdges[i]);
    }

    
    //Calculate distances for every node in the graph versus the root node
    while(E.length) {
        var current = E.shift();
        if(!distances[current]) {
            distances[current] = bfs(graph,current);
        }
        for (var i=0;i<Math.min(distances[current].furthestNodes.length,1);i++) {
            var n = distances[current].furthestNodes[i];
                if (!edges.includes(n)) {
                    edges.push(n);
                    E.push(n);
                }    
        }
            
    }  

    return edges;

};


function findTreeDistances(graph, distances) {
    var startingNode = 1;   //Assign node 1 as initial node
    
    var edges = [];
    
    //Calculate furthest edges from Node 1 as starting.point
    distances[startingNode] = bfs(graph,startingNode); 
 
 
    var edge1 = distances[startingNode].furthestNodes[0];  //Edge node
        
    //Calculate distances for every node in the graph versus the edge node
    distances[edge1] = bfs(graph,edge1);
    
    if(distances[startingNode].maxDistance==distances[edge1].maxDistance) {
        edges = [startingNode,edge1]
    }
    else {
        var edge2 = distances[edge1].furthestNodes[0];  //Edge node
        distances[edge2] = bfs(graph,edge2);
        edges = [edge1,edge2];
    }
    
    return edges;

};


/*The second parameter is to store the height of tree.
   Initially, we need to pass a pointer to a location with value
   as 0. So, function should be used as follows:
 
   int height = 0;
   struct node *root = SomeFunctionToMakeTree();
   int diameter = diameterOpt(root, &height); */

function diameterOpt(graph, node, previousNode, height)
{
  /* lh --> Height of left subtree
     rh --> Height of right subtree */
  var children = graph[node].adjNodes;
    console.log("Node: " + node);
    console.log("AdjNodes: " + children);
    console.log("Previous Node: " + previousNode);
    
    
  if(children.indexOf(previousNode) > -1)
      children.splice(children.indexOf(previousNode),1);
 
      console.log("Children: " + children);   
      
      
  if(!children.length)
  {
     height = 0;
     return 0; /* diameter is also 0 */
  }      
    
  var heightArr = [];
  var diameterArr = [];  
  for(var i=0;i<children.length;i++) {
      heightArr[i] = 0;
      diameterArr[i] = 0;
  } 
  

  /* Get the heights of left and right subtrees in lh and rh
    And store the returned values in ldiameter and ldiameter */
    
  for(var i=0;i<children.length;i++) {      
      diameterArr[i] = diameterOpt(graph,children[i],node,heightArr[i]);
  }   
      
  /* Height of current node is max of heights of left and
     right subtrees plus 1*/
  height = Math.max(heightArr) + 1;

  var h1,h2 = 0;
  for(var i=0;i<heightArr[i].length;i++) {
      if(heightArr[i] > h1) {
          h2 = h1;
          h1 = heightArr[i]
      }
      else if(heightArr[i] > h2) {
          h2 = heightArr[i];
      }
  }       
    
    console.log("H1: " + h1);
  console.log("H2: " + h2);
  console.log("Array of diameters: " + diameterArr);    
    
  return Math.max(h1 + h2 + 1, Math.max(diameterArr));
}



 
/* Function to get diameter of a binary tree */
function treeDiameter(tree,node,previousNode, rootNode,distances, edge)
{
    
    if(previousNode==0) {
        distances[rootNode] = {};
        distances[rootNode][rootNode] = 0;
    }
    else {
        distances[rootNode][node] = distances[rootNode][previousNode] + 1;
    }
        
    var children = JSON.parse(JSON.stringify(tree[node].adjNodes));
    

        
    if(children.indexOf(previousNode) > -1)
        children.splice(children.indexOf(previousNode),1);
  
    
    if(!children.length) {
        return 1;
    }    
    else {
        /* get the height of sub-trees */
        var subtreeHeights = [];
        for(var i=0;i<children.length;i++) {
            subtreeHeights[i] = treeHeight(tree,children[i],node);
        }
        
     
        /* get the height of sub-trees */
        var subtreeDiameters = [];
        for(var i=0;i<children.length;i++) {          
            subtreeDiameters[i] = treeDiameter(tree,children[i],node, rootNode, distances, edge);
        }    
        
        /* Return max of following three
        1) Diameter of children subtrees
        2) Height of 2 max subtree  heights + 1 */
        
        var h1 = 0;
        var h2 = 0;
        if(subtreeHeights.length<2) {
            h1 = subtreeHeights[0];
            h2 = 0;
        } 
        else {
            for(var i=0;i<subtreeHeights.length;i++) {
                if(subtreeHeights[i] > h1) {
                    h2 = h1;
                    h1 = subtreeHeights[i];
                }
                else if(subtreeHeights[i] > h2) {
                    h2 = subtreeHeights[i];
                }
            } 
        }
        
        return Math.max(h1 + h2 + 1, Math.max.apply(Math,subtreeDiameters));
        
    }    
} 
 
/* UTILITY FUNCTIONS TO TEST diameter() FUNCTION */
 
/*  The function Compute the "height" of a tree. Height is the 
    number f nodes along the longest path from the root node 
    down to the farthest leaf node.*/
function treeHeight(tree,node,previousNode)
{    
    var c = JSON.parse(JSON.stringify(tree[node].adjNodes));
    if(c.indexOf(previousNode) > -1)
        c.splice(c.indexOf(previousNode),1);
    
    if(!c.length) {
        return 1;
    } else {
        var h = [];
        for (var i=0;i<c.length;i++) {
            h[i] = treeHeight(tree,c[i],node);      
        }

            
        /* If tree is not empty then height = 1 + max of subtree heights */   
        return 1 + Math.max.apply(Math,h);
    }
} 

Journey Scheduling Python Solution

import math
import os
import random
import re
import sys
sys.setrecursionlimit(10**9)

#
# Complete the 'journeyScheduling' function below.
#
# The function is expected to return an INTEGER_ARRAY.
# The function accepts following parameters:
#  1. INTEGER n
#  2. 2D_INTEGER_ARRAY roads
#  3. 2D_INTEGER_ARRAY journeys
#

def journeyScheduling(n, roads, journeys):
    # Write your code here
    adj_list = [[] for i in range(n+1)]
    for u, v in roads:
        adj_list[u].append(v)
        adj_list[v].append(u)
    
    start = 1
    down_max_one = [(0, None)] * (n+1)
    down_max_two = [0] * (n+1)
    visited = [False] * (n+1)
    queue = [(start, None)]
    
    while len(queue):
        edge = queue.pop()
        u, p = edge
        if not visited[u]:
            queue.append(edge)
            visited[u] = True
            for v in adj_list[u]:
                if visited[v]:
                    continue
                # dfs_down(v)
                queue.append((v, u))
            
            continue
        
        d_one = 0
        nl_one = None
        d_two = 0
        nl_two = None
        for v in adj_list[u]:
            if v == p:
                continue
            d_v_one, nl_v_one = down_max_one[v]
            d_v_one += 1
            if d_v_one > d_one:
                d_two = d_one
                # nl_two = nl_one
                d_one = d_v_one
                nl_one = v

            elif d_v_one >= d_two:
                d_two = d_v_one
                # nl_two = v
                                    
        down_max_one[u] = (d_one, nl_one)
        down_max_two[u] = d_two
    
    # dfs_down(start)
        
    visited = [False] * (n+1)
    up_max = [0] * (n+1)
    dist_max = [0] * (n+1)
    queue = [(start, None)]
    
    while len(queue):
        edge = queue.pop()
        u, p = edge
        visited[u] = True

        if p is None:
            up_u = 0
            # up_nl_u = None#set()
        else:
            up_p = up_max[p]
            up_u_p = up_p + 1
            d_p_one, d_nl_p_one = down_max_one[p]
            d_p_two = down_max_two[p]
            
            if u != d_nl_p_one:
                d_p_v = d_p_one + 1
            else:
                d_p_v = d_p_two + 1
            
            up_u = max(up_u_p, d_p_v)
            
        up_max[u] = up_u
        d_u, d_nl_u = down_max_one[u]
        
        dist_max[u] = max(d_u, up_u)
        
        for v in adj_list[u]:
            if visited[v]:
                continue
            queue.append((v, u))


    # dfs_max_dist(start, None)
    diameter = max(dist_max)
    
    # print(diameter)
    # print(dist_max)
    m = len(journeys)
    res = [0] * m
    for i in range(m) :
        v, k = journeys[i]
        max_v = dist_max[v]
        res[i] = max_v + (k-1)*diameter
    return res
    

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')

    first_multiple_input = input().rstrip().split()

    n = int(first_multiple_input[0])

    m = int(first_multiple_input[1])

    roads = [[] for i in range(n-1)]

    for i in range(n - 1):
        road_inputs = input().rstrip().split()
        roads[i] = (int(road_inputs[0]), int(road_inputs[1]))

    journeys = [[] for i in range(m)]

    for j in range(m):
        journey_inputs = input().rstrip().split()
        journeys[j] = (int(journey_inputs[0]), int(journey_inputs[1]))

    result = journeyScheduling(n, roads, journeys)
    # result = [0, 11]
    fptr.write('\n'.join(map(str, result)))
    fptr.write('\n')

    fptr.close()
c C# C++ HackerRank Solutions java javascript python CcppCSharpHackerrank Solutionsjavajavascriptpython

Post navigation

Previous post
Next post
  • 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