Question

I can't seem to figure out a way to list down the vertices passed as my algorithm (floyd-warshall) computes for the shortest path. I've been told that I would have to use recursion, but I don't know how to use recursion. Please give pseudocode/examples, greatly appreciated!

    import java.util.*;
    public class Main{
        public static final int INF = 9999999;
        public static int[][] path;
        public static int[] tax;
        public static void main(String[] adsf){
            Scanner pp = new Scanner(System.in);
            int testCases = pp.nextInt();
            pp.nextLine();
            pp.nextLine();
            while(testCases-- >0){
                String[] s1 = pp.nextLine().split(" ");
                int size = s1.length;
                path = new int[size][size];
                for(int i = 0; i < path.length; i++)
                    Arrays.fill(path[i],INF);
                tax = new int[size];
                for(int j = 0; j < path[0].length; j++){
                    path[0][j] = Integer.parseInt(s1[j]);
                    if(path[0][j]==-1)path[0][j]=INF;
                }
                for(int i = 1; i < path.length;i++){
                    s1 = pp.nextLine().split(" ");
                    for(int j = 0; j < path[0].length; j++){
                        path[i][j] = Integer.parseInt(s1[j]);
                        if(path[i][j]==-1)path[i][j]=INF;
                    }
                }
                for(int k=0; k<tax.length;k++){
                    tax[k] = pp.nextInt();
                } pp.nextLine();    
                sssp();
                }
                int x,y;
                while(pp.hasNextInt()){
                    x=pp.nextInt();
                    y=pp.nextInt();
                    int cost = path[x-1][y-1];
                    System.out.println((x-1)+" "+(y-1)+" "+cost);
                }
            }
        }
        public static void sssp(){
            for(int k=0;k<path.length;k++){
                for(int i=0;i<path.length;i++){
                    for(int j=0;j<path.length;j++){
                        path[i][j] = Math.min(path[i][j],path[i][k]+path[k][j]);
                    }
                }   
            }
        }
    }
Was it helpful?

Solution

You do not need to use recursion for path reconstruction (in fact, you never have to use recursion in Java, it just happens to be a lot more convenient to use it to solve certain problems, including this one).

In order to be able to figure out the shortest path in addition to the length, you need a second 2D array that stores successors of your node in the path. Take a look at this article, the array I am talking about is called next in their pseudocode.

Recall that the logic of the algorithm goes as follows: "if you can get from i to j through k faster than going from i to j through any previously discovered path, then use the path though k as your current shortest path". Now all you need to do is to store the decision to go through k in some other array, like this:

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

Once Floyd-Warshal finishes, you can reconstruct the path from i to j by first reconstructing the path from i to k and then from k to j.

String GetPath (int i, int j) {
    if (path[i][j] == INF) return "no path";
    int intermediate = next[i][j];
    if (intermediate < 0) return " ";
    return GetPath(i,intermediate) + intermediate + GetPath(intermediate,j);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top