本文主要是介绍数据结构重读——单源最短路径(Dijkstra) 转自酷勤,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
单源最短路径:给定带权有向图和源点v,求从v到G中其余各点的最短路径。
Dijkstra算法非常类似于最小生成树算法(的Prim)。
算法:
0、假设源为v0,设置辅助变量dist和pre,优先队列pq,按照dist[x]从小到达排序(小顶堆)。
1、如果v0->i连通,初始化dist[i]为w[v0][i]。放(dist[i], i)入pq。
2、循环,直到pq为空。
2.1、取出pq中最小的,设其下标为x,
2.2、遍历图matrix[x][i], i 0->nvexs。如果dist[x]+matrix[x][i] < dist[i],更新dist[i]=dist[x]+matrix[x][i],并且放(dist[i], i)入pq,并且pre[i] = x。
3、如果dist[i]<INFINTE,输出dist[i],并倒序输出pre[?]直到为-1。
上述这么搞,时间复杂度应该为O(nlogn)
好了,代码如下:
图及输入
01 | import java.util.Arrays; |
02 | import java.util.Scanner; |
07 | scan = new Scanner(System.in); |
15 | private void intput_vexs() { |
18 | System.out.println( "Please enter n for vexs:" ); |
19 | if (scan.hasNextInt()) { |
20 | nvexs = scan.nextInt(); |
22 | vexs = new int [nvexs]; |
23 | for ( int i = 0 ; i < nvexs; i++) { |
24 | System.out.println( "Please enter a integer for vex(" + i + "):" ); |
25 | if (scan.hasNextInt()) { |
26 | vexs[i] = scan.nextInt(); |
31 | private void input_arcs() { |
33 | int nvexs = vexs.length; |
34 | matrix = new int [nvexs][]; |
35 | for ( int i = 0 ; i < nvexs; i++) { |
36 | matrix[i] = new int [nvexs]; |
37 | Arrays.fill(matrix[i], Integer.MAX_VALUE); |
40 | int x = 0 , y = 0 , w = 0 ; |
41 | System.out.println( "Please enter n for arcs:" ); |
42 | if (scan.hasNextInt()) { |
43 | narcs = scan.nextInt(); |
45 | for ( int i = 0 ; i < narcs; i++) { |
46 | System.out.println( "Please enter x, y, w for arc(" + i + "):" ); |
47 | if (scan.hasNextInt()) { |
51 | if (scan.hasNextInt()) { |
55 | if (scan.hasNextInt()) { |
58 | if (x == - 1 || y == - 1 || w <= 0 ) { |
59 | System.out.println( "x or y or w invalid, please enter again:" ); |
67 | public int vex2i( int v) { |
68 | for ( int i = 0 ; i < vexs.length; i++) { |
76 | public int [][] matrix = null ; |
77 | public int [] vexs = null ; |
78 | private Scanner scan = null ; |
80 | public static void main(String[] args) { |
81 | Graph g = new Graph(); |
83 | System.out.println( "vexs:" ); |
84 | for ( int i = 0 ; i < g.vexs.length; i++) { |
85 | System.out.print(g.vexs[i] + " " ); |
88 | System.out.println( "matrix:" ); |
89 | for ( int i = 0 ; i < g.matrix.length; i++) { |
90 | for ( int j = 0 ; j < g.matrix[i].length; j++) { |
91 | System.out.format( "%11d " , g.matrix[i][j]); |
Dijkstra算法:
01 | import java.util.Comparator; |
02 | import java.util.PriorityQueue; |
06 | public DijPair( int i, int w) { |
15 | public class Dijkstra { |
17 | public void SetGraph(Graph g) { |
21 | public void ShortPath( int start) { |
23 | int v = g.vex2i(start); |
25 | System.out.println( "start vex " + start + " invalid" ); |
28 | PriorityQueue<DijPair> pq = new PriorityQueue<DijPair>( 10 , |
29 | new Comparator<DijPair>() { |
31 | public int compare(DijPair a, DijPair b) { |
36 | int dist[] = new int [g.vexs.length]; |
37 | int pre[] = new int [g.vexs.length]; |
38 | for ( int i = 0 ; i < g.matrix[v].length; i++) { |
40 | dist[i] = g.matrix[v][i]; |
41 | if (dist[i] != Integer.MAX_VALUE) { |
43 | pq.add( new DijPair(i, dist[i])); |
47 | while (!pq.isEmpty()) { |
49 | DijPair cur = pq.poll(); |
54 | for ( int i = 0 ; i < g.matrix[cur.i].length; i++) { |
55 | if (g.matrix[cur.i][i] != Integer.MAX_VALUE |
56 | && dist[cur.i] + g.matrix[cur.i][i] < dist[i]) { |
57 | dist[i] = dist[cur.i] + g.matrix[cur.i][i]; |
59 | pq.add( new DijPair(i, dist[i])); |
64 | for ( int i = 0 ; i < dist.length; i++) { |
65 | if (dist[i] != Integer.MAX_VALUE) { |
66 | System.out.format( "short_dist %d to %d is %d " , start, |
68 | System.out.print( ", path is " ); |
69 | System.out.format( "%d " , g.vexs[i]); |
72 | System.out.format( "<- %d " , g.vexs[tmp]); |
80 | private Graph g = null ;; |
82 | public static void main(String[] args) { |
83 | Graph g = new Graph(); |
85 | Dijkstra dij = new Dijkstra(); |
测试图:

测试数据:
测试输出:
1 | short_dist 0 to 2 is 10 , path is 2 <- 0 |
2 | short_dist 0 to 3 is 50 , path is 3 <- 4 <- 0 |
3 | short_dist 0 to 4 is 30 , path is 4 <- 0 |
4 | short_dist 0 to 5 is 60 , path is 5 <- 3 <- 4 <- 0 |
这篇关于数据结构重读——单源最短路径(Dijkstra) 转自酷勤的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!