使用Dirkstra算法完成有权单源最短路径的算法,回忆一下当初学数据结构最难的图的部分,注意里面距离和收录点之间的运算关系,以及Dijkstra算法的步骤。示例为总共五个城市,五条路,城市编号从0到4,起始点为0,终点为3,路径为:0 - 4 => 5;0 - 1 => 2; 0 - 2 =>2; 1 - 3 =>1 ; 2 - 3 =>2;总共五条路径。
import java.util.*;
public class Dijkstra {
static int[] dist; //记录最短路径
static int[][] map; //图的存储,邻接矩阵
static boolean[] visited; //收录使用
static int M,N; //M个城市,N条路
static int start,end; //城市起点和终点
static final int maxINF = 1 << 30;
static int[] path; //记录经过的路径
static void dijkstra(){
dist[start] = 0; //起点距离为0
visited[start] = true; //收录起点
Arrays.fill(path, -1);
for( int i = 0 ; i < M ;i++) //初始化起点
if( map[start][i] != maxINF ){
dist[i] = map[start][i];
path[i] = start;
}
while(true){
int findMin = maxINF;
int u = 0;
for( int i = 0 ; i < M ; i++) //寻找当前未被收录且dist中最小的值
if( !visited[i] && dist[i] < findMin){
u = i;
findMin = dist[i];
}
if( findMin == maxINF) //均被访问过
break;
visited[u] = true; //收录该顶点
for( int i = 0 ; i < M ; i++){
if( !visited[i] && dist[u] + map[u][i] < dist[i]){
dist[i] = dist[u] + map[u][i];
path[i] = u;
}
}
}
}
static void printPath(){ //利用堆栈实现输出路径
Deque<Integer> stack = new ArrayDeque<Integer>();
int e = end;
while( path[e] != -1){
stack.push(e);
e = path[e];
}
System.out.print(start+" ");
while( !stack.isEmpty()){
int n = stack.pop();
System.out.print(n+" ");
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
M = input.nextInt(); //0 - M-1总共M个城市
map = new int[M][M];
dist = new int[M];
visited = new boolean[M];
path = new int[M];
for( int i = 0 ; i < M ; i++)
Arrays.fill(map[i], maxINF); //图的每一个节点初始化长度为无穷大
Arrays.fill(dist, maxINF); //dist定义为正无穷大
Arrays.fill(visited, false);
N = input.nextInt(); //N条路
start = input.nextInt(); //出发城市
end = input.nextInt(); //终点城市
for( int i = 0 ; i < N ; i++){
int x = input.nextInt();
int y = input.nextInt();
int d = input.nextInt();
map[x][y] = d;
}
dijkstra();
/*for( int i = 0 ; i < M ; i++){
for( int j = 0 ; j < M ; j++)
System.out.print(map[i][j]+" ");
System.out.println();
}
for( int i = 0 ; i < M ; i++)
System.out.print(dist[i]+" ");
System.out.println();
for( int i = 0 ; i < M ; i++)
System.out.print(path[i]+" ");
System.out.println();*/
System.out.println(dist[end]);
printPath();
}
}