// Arup Guha
// 6/25/02
// Floyd Warshall's algorithm: an example of dynamic programming.
// Slightly edited on 5/9/2015

import java.util.*;

public class floyd {

  	public static void shortestpath(int[][] adj, int[][] path) {

    	int n = adj.length;

    	// Compute successively better paths through vertex k.
    	for (int k=0; k<n;k++) {

      		// Do so between each possible pair of points.
      		for (int i=0; i<n; i++) {
        		for (int j=0; j<n;j++) {

          			if (adj[i][k]+adj[k][j] < adj[i][j]) {
          				adj[i][j] = adj[i][k]+adj[k][j];
          				path[i][j] = path[k][j];
          			}
          		}
      		}
    	}
  	}

  	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);

    	// Tests out algorithm with graph shown in class.
    	int[][] m = new int[5][5];
    	m[0][0] = 0; m[0][1] = 3; m[0][2] = 8; m[0][3] = 10000; m[0][4] = -4;
    	m[1][0] = 10000; m[1][1] = 0; m[1][2] = 10000; m[1][3] = 1;
    	m[1][4]=7;
    	m[2][0] = 10000; m[2][1] = 4; m[2][2] = 0; m[2][3] = 10000;
    	m[2][4] = 10000;
    	m[3][0] = 2; m[3][1] = 10000; m[3][2] = -5; m[3][3] = 0;
    	m[3][4] = 10000;
    	m[4][0] = 10000; m[4][1] = 10000; m[4][2] = 10000; m[4][3] = 6;
    	m[4][4] =0;
    	int[][] path = new int[5][5];

    	// Initialize with the previous vertex for each edge. -1 indicates
    	// no such vertex.
    	for (int i=0; i<5; i++)
    		for (int j=0; j<5; j++)
    			if (m[i][j] == 10000)
    				path[i][j] = -1;
    			else
    				path[i][j] = i;

    	shortestpath(m, path);

		// Prints out shortest distances.
    	for (int i=0; i<5;i++) {
      		for (int j=0; j<5;j++)
        		System.out.print(m[i][j]+" ");
      		System.out.println();
    	}

    	System.out.println("From where to where do you want to find the shortest path?(0 to 4)");
    	int start = stdin.nextInt();
    	int end = stdin.nextInt();

    	// The path will always end at end.
    	String myPath = end + "";

    	// Loop through each previous vertex until you get back to start.
    	while (path[start][end] != start) {
    		myPath = path[start][end] + " -> " + myPath;
    		end = path[start][end];
    	}

    	// Just add start to our string and print.
    	myPath = start + " -> " + myPath;
    	System.out.println("Here's the path "+myPath);

  	}
}
