-1

How would you go about implementing Dijkstra's algorithm using binary heaps? My goal is to have a runtime of O(M log N).

Say there are N cities in a kingdom, M train routes in this kingdom, and S is the capital city.

Th input is N M S followed by a list of M-separated triplets (U, V, and D) meaning there is a train route going from city U to city V that takes D days. Note that this train route can only go from city U to V and not from V to U.

The output is one line containing a space-separated list of N integers, where the I-th integer is the minimum number of days to travel from city I to city S. If it is impossible to travel from city I to city S, output  - 1 for the I-th integer.

If a sample input is this:

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

Then the output is:

 1 -1 3 0

Here's another example:

 5 8 2
 3 2 2
 2 3 2
 2 5 2
 5 2 2
 4 2 2
 2 4 2
 1 4 2
 2 1 2

The output is:

 4 0 2 2 2

My goal is to try to use binary heaps to solve this, but I'm having trouble doing so. I'm using an adjacency list right now and I'll see if I can post the code on this, but it would really help if you could help me.

Thanks for all your help.

EDIT: Here's the code I have using an adjacency list.

//import static jdk.nashorn.internal.runtime.regexp.joni.Syntax.Java;

import java.util.Scanner;

public class Dijkstra { public static void main(String[] args) {

int N, M, S;

Scanner scan = new Scanner(System.in);
N = scan.nextInt(); // # cities
M = scan.nextInt(); // # train routes
S = scan.nextInt(); // capital city
// System.out.println(N + " " + M + " " + S);


// NOW THE ARRAYS
int [][] A = new int[50010][60]; // the neighbors of each city
int [][] W = new int[50010][60]; // the weights of going to neighbors
int []   deg = new int[50010]; // the degree of the city
// The limits are 50,010 and 60 because the problem statement said that there are at most
// 50,000 cities, and we just added 10 just to be sure. We have 60 because the maximum number of
// train routes is 50, and we just added 10 to that.

// with each incoming vertex/city, we will at first initialize the degree to be 0
for(int i = 1; i <=N; ++i) {
  deg[i] = 0;  // initialize the degree of each vertex to 0
}

// this is for each of the train routes
for(int i = 1; i <= M; ++i) {
  int u, v, w;
  u = scan.nextInt(); // origin
  v = scan.nextInt(); // destination
  w = scan.nextInt(); // # days
  // System.out.println(u + " " + v + " " + w);

  // WITH THE ARRAYS
  A[u][deg[u]] = v; // adding an edge (u,v) to the graph where u is origin and deg[u] is weight
  W[u][deg[u]] = w; // set its weight to w, the number of days it takes
  deg[u]++; // increase degree of vertex u by 1
}

//for(int i = 1; i <= N; ++i) {
//  System.out.println("vertex:" + i + "'s neighbors");
//  for(int j = 0; j < deg[i]; ++j) {
//    System.out.println(A[i][j] + " " + W[i][j]);
//  }
//}




// compute distance from U (origin) to S (capital city) by Dijkstra's algorithm
// Dijkstra's algorithm: find the shortest path distance from each vertex to the capital
for(int U = 1; U <= N; ++U) {

  // INITIALIZATION
  int[] visited = new int[50010]; // create an empty array w/ max # cities space for cities that are visited
  int[] dist = new int[50010]; // create an empty array w/ max # cities space for distance of each city
  // loop that goes through the arrays and fills in values up to N number of cities
  for(int V = 1; V <= N; ++V) {
    dist[V] = 100000000; // set the distance of the city to the capital to be the maximum possible number
    visited[V] = 0; // set the cities that are visited to be 0
  }

  // ACTUAL ALGORITHM
  dist[U] = 0; // set the distance of the city to be 0

  for(int k = 1; k <= N; ++k) {
    //find an unvisited vertex with minimum distance
    int min = 100000000;
    int minVertex = 1;

    for(int i = 1; i<=N; ++i) {
      // if the city has not been visited and the distance from it to the capital is less than the minimum
      if(visited[i] == 0 && dist[i] < min) {
        min = dist[i]; // set the new minimum to be this distance
        minVertex = i; // set the minimum vertex to be this number
      }
    }

    visited[minVertex] = 1; // set this value to 1 to show that the city has been visited

    // relax the edges that are adjacent to minVertex to update the shortest path distance to
    // neighbors of minVertex
    for(int j = 0; j < deg[minVertex]; ++j) { // this is updating the minimum weight of the city
      // A[minVertex][j] is the j-th neighbor of minVertex
      // W[minVertex][j] is the weight of the corresponding edge
      int newDist = dist[minVertex] + W[minVertex][j];
      if (newDist < dist[A[minVertex][j]]) {
        dist[A[minVertex][j]] = newDist;
      }
    }
  }

  if(dist[S] == 100000000) { // if the distance of this city is still the maximum, it does not have a connection
    System.out.print("-1 ");
  }
  else { // if it has a distance less than max, it means there is a minimum distance and we will print that
    System.out.print(dist[S] + " ");
  }

}

System.out.println("");

}

}

  • As a general rule for this site, you should post some code in your question to show us what you've already tried. – ubadub Dec 02 '17 at 22:11
  • you didn't say what your program is supposed to find. – Matt Timmermans Dec 02 '17 at 22:23
  • @ubadub Sorry I'm new to this site. I posted the code that I had above – Ashley Winters Dec 02 '17 at 22:34
  • @MattTimmermans I'm supposed to output one line containing a space-separated list of N integers where the I-th integer is the minimum number of days to travel from city I to city S (the capital city). If it is not possible to travel from city I to city S, output -1 for the I-th integer. – Ashley Winters Dec 02 '17 at 22:37
  • 1
    Reverse the train routes and calculate the time it takes to get from S to all I instead. – Matt Timmermans Dec 02 '17 at 22:44
  • @MattTimmermans That would work, but the train routes are directed, so in my first example input where city 4 (the capital city) goes to city 2, the decision will be that city 2 will not be able to reach city 4. Am I understanding correctly? – Ashley Winters Dec 02 '17 at 22:47
  • Reverse the train routes – Matt Timmermans Dec 02 '17 at 23:01

1 Answers1

0

To get that time complexity, you need to use Minor priority queue which makes use of heap(which is not fully sorted structure). For more infor look here.

The idea of using heap is that you put all succesors of the any node in the priotity queue which is implemented with the help of heap and remove node which has minimum cost from queue. Because Heap structure is not fully sorted and inserting a node in heap/queue is ~logN and you can also get more info on this here

Luai Ghunim
  • 976
  • 7
  • 14