Как вывести список вершин, переданных в алгоритме Флойда-Варшалла
Кажется, я не могу найти способ перечислить переданные вершины, поскольку мой алгоритм (floyd-warshall) вычисляет для кратчайшего пути. Мне сказали, что мне придется использовать рекурсию, но я не знаю, как использовать рекурсию. Пожалуйста, дайте псевдокод / примеры, с благодарностью!
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]);
}
}
}
}
}
1 ответ
Вам не нужно использовать рекурсию для восстановления пути (фактически, вам никогда не приходилось использовать рекурсию в Java, просто оказалось, что ее гораздо удобнее использовать для решения определенных проблем, в том числе и этой).
Чтобы иметь возможность определить кратчайший путь в дополнение к длине, вам необходим второй 2D-массив, в котором хранятся преемники вашего узла на пути. Посмотрите на эту статью, массив, о котором я говорю, называется next
в их псевдокоде.
Напомним, что логика алгоритма выглядит следующим образом: "Если вы можете получить от i
в j
через k
быстрее, чем идти от i
в j
через любой ранее обнаруженный путь, затем используйте путь, хотя k
как ваш текущий кратчайший путь ". Теперь все, что вам нужно сделать, это сохранить решение пройти k
в другом массиве, например:
if (path[i][k] + path[k][j] < path[i][j]) {
path[i][j] = path[i][k]+path[k][j];
next[i][j] = k;
}
Как только Флойд-Варшал закончит, вы можете восстановить путь из i
в j
сначала восстановив путь из i
в k
а затем из k
в 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);
}