最短路径算法——Dijkstra(迪杰斯特拉) Java+PriorityQueue版
本文非解释原理,学习Dijkstra原理可参考 : 最短路径问题—Dijkstra算法详解
最近在备战天梯赛,遇到最短路问题,于是整理了下模板,较好理解+简易,其中利用了PriorityQueue,优化找最值的过程,减少了代码量。
import java.util.*;
public class Dijkstra {
static class Edge {
int to, weight;
public Edge(int to, int weight) {
this.to = to;
this.weight = weight;
}
}
static int INF = Integer.MAX_VALUE;
static int[] dist;
static int[] prev;
static boolean[] visited;
static List<List<Edge>> graph;
public static void dijkstra(int start) {
PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return dist[o1] - dist[o2];
}
});
pq.offer(start);
dist[start] = 0;
while (!pq.isEmpty()) {
//取出距离start最近的点
int u = pq.poll();
visited[u] = true;
//遍历u的每条边u-v,如果能通过u使得start到v的距离变得更短,更新start到v的距离dist[v]
for (Edge e : graph.get(u)) {
int v = e.to;
int weight = e.weight;
if (!visited[v] && dist[v] > dist[u] + weight) {
dist[v] = dist[u] + weight;
//记录前驱节点
prev[v] = u;
//将v加入优先队列,下次参与比较距离start最近的点
pq.offer(v);
}
}
}
}
public static List<Integer> getShortestPath(int start, int end) {
List<Integer> path = new ArrayList<>();
for (int v = end; v != start; v = prev[v]) {
path.add(v);
}
path.add(start);
Collections.reverse(path);
return path;
}
public static void main(String[] args) {
int n = 5;
int start = 0;
int end = 3;
dist = new int[n];
prev = new int[n];
visited = new boolean[n];
Arrays.fill(dist, INF);
Arrays.fill(prev, -1);
graph = new ArrayList<>();
for (int i = 0; i < n; i++) {
graph.add(new ArrayList<>());
}
//get某点,add某边(终点,权重)
graph.get(0).add(new Edge(1, 10));
graph.get(0).add(new Edge(4, 3));
graph.get(1).add(new Edge(2, 2));
graph.get(1).add(new Edge(4, 4));
graph.get(2).add(new Edge(3, 9));
graph.get(3).add(new Edge(2, 7));
graph.get(3).add(new Edge(0, 6));
graph.get(4).add(new Edge(1, 1));
graph.get(4).add(new Edge(2, 8));
graph.get(4).add(new Edge(3, 2));
dijkstra(start);
System.out.println("Distance from " + start + " to " + end + " is " + dist[end]);
List<Integer> shortestPath = getShortestPath(start, end);
System.out.println("Shortest path: " + shortestPath.toString());
}
}