java实现有权图中的最短路径问题--迪杰斯特拉算法(Dijkstra)

1.什么是Dijkstra算法

Dijkstra算法,是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题(应用于无权图或所有边权相等的图时,等同于BFS)。其主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

 

2.算法思想

把顶点集合V分成两组:

(1)S:已求出的顶点的集合(初始时只含有源点V0)

(2)V-S=T:尚未确定的顶点集合

将T中顶点按递增的次序加入到S中,保证:

(1)从源点V0到S中其他各顶点的长度都不大于从V0到T中任何顶点的最短路径长度

(2)每个顶点对应一个距离值

S中顶点:从V0到此顶点的长度

T中顶点:从V0到此顶点的只包括S中顶点作中间顶点的最短路径长度

依据:可以证明V0到T中顶点Vk的,或是从V0到Vk的直接路径的权值;或是从V0经S中顶点到Vk的路径权值之和

 

 

3.算法步骤

G={V,E}

1. 初始时令 S={V0},T=V-S={其余顶点},T中顶点对应的距离值

若存在<V0,Vi>,d(V0,Vi)为<V0,Vi>弧上的权值

若不存在<V0,Vi>,d(V0,Vi)为∞

2. 从T中选取一个与S中顶点有关联边且权值最小的顶点W,加入到S中

3. 对其余T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的距离值缩短,则修改此距离值

重复上述步骤2、3,直到S中包含所有顶点,即W=Vi为止

 

4.实现代码

 

​
import java.util.Scanner;

public class Dijstra {

    public static int Max = 100001;

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        System.out.println("请输入顶点数和边数:");
        int vertex = input.nextInt(); //顶点数
        int edge = input.nextInt();//边数

        int[][] matrix = new int[vertex][vertex];

        //初始化邻接矩阵
        for (int i = 0; i < vertex; i++)
            for (int j = 0; j < vertex; j++)
                matrix[i][j] = Max;

        System.out.println("请输入两个顶点号及他们之间的路径长度(结束时请输入0):");
        for (int i = 0; i < edge; i++) {
            int source = input.nextInt();
            int target = input.nextInt();
            int weight = input.nextInt();
            matrix[source][target] = weight;
        }

        //单源最短路径,源点
        int source = input.nextInt();
        //调用dijstra算法计算最短路径
        dijstra(matrix, source);
    }

    public static void dijstra(int[][] matrix, int source) {

        int[] shortest = new int[matrix.length];//最短路径长度

        int[] visited = new int[matrix.length];//判断该点的最短路径是否求出

        String[] path = new String[matrix.length];//存储输出路径

        //初始化输出路径
        for (int i = 0; i < matrix.length; i++)
            path[i] = new String(source + "->" + i);


        //初始化源节点
        shortest[source] = 0;
        visited[source] = 1;

        for (int i = 1; i < matrix.length; i++) {
            int min = Integer.MAX_VALUE;
            int index = -1;

            for (int j = 0; j < matrix.length; j++) {
                //判断加入新的节点后是否存在更短路径
                if (visited[j] == 0 && matrix[source][j] < min) {
                    min = matrix[source][j];
                    index = j;
                }
            }

            //更新最短路径,标记计算过的最短路径的节点
            shortest[index] = min;
            visited[index] = 1;

            //更新从index跳到其它节点的较短路径
            for (int m = 0; m < matrix.length; m++) {
                if (visited[m] == 0 && matrix[source][index] + matrix[index][m] < matrix[source][m]) {
                    matrix[source][m] = matrix[source][index] + matrix[index][m];
                    path[m] = path[index] + "->" + m;
                }
            }

            //打印最短路径
            for (int n = 0; n < matrix.length; n++) {
                if (n != source) {
                    if (shortest[n] == Max) {
                        System.out.println(source + "到" + n + "不可达");
                    } else {
                        System.out.println(source + "到" + n + "的最短路径是:" + path[n] + ",最短距离是:" + shortest[n]);
                    }
                }
            }
        }
    }
}

 输入样例

7 10

0 1 6

1 2 5

0 3 2

3 1 7

3 4 5

1 2 5

1 5 3

4 5 5

5 4 2

4 6 1

0

输出样例

0到1的最短路径是:0->1,最短距离是:0
0到2的最短路径是:0->2,最短距离是:0
0到3的最短路径是:0->3,最短距离是:2
0到4的最短路径是:0->3->4,最短距离是:0
0到5的最短路径是:0->5,最短距离是:0
0到6的最短路径是:0->6,最短距离是:0
0到1的最短路径是:0->1,最短距离是:6
0到2的最短路径是:0->1->2,最短距离是:0
0到3的最短路径是:0->3,最短距离是:2
0到4的最短路径是:0->3->4,最短距离是:0
0到5的最短路径是:0->1->5,最短距离是:0
0到6的最短路径是:0->6,最短距离是:0
0到1的最短路径是:0->1,最短距离是:6
0到2的最短路径是:0->1->2,最短距离是:0
0到3的最短路径是:0->3,最短距离是:2
0到4的最短路径是:0->3->4,最短距离是:7
0到5的最短路径是:0->1->5,最短距离是:0
0到6的最短路径是:0->3->4->6,最短距离是:0
0到1的最短路径是:0->1,最短距离是:6
0到2的最短路径是:0->1->2,最短距离是:0
0到3的最短路径是:0->3,最短距离是:2
0到4的最短路径是:0->3->4,最短距离是:7
0到5的最短路径是:0->1->5,最短距离是:0
0到6的最短路径是:0->3->4->6,最短距离是:8
0到1的最短路径是:0->1,最短距离是:6
0到2的最短路径是:0->1->2,最短距离是:0
0到3的最短路径是:0->3,最短距离是:2
0到4的最短路径是:0->3->4,最短距离是:7
0到5的最短路径是:0->1->5,最短距离是:9
0到6的最短路径是:0->3->4->6,最短距离是:8
0到1的最短路径是:0->1,最短距离是:6
0到2的最短路径是:0->1->2,最短距离是:11
0到3的最短路径是:0->3,最短距离是:2
0到4的最短路径是:0->3->4,最短距离是:7
0到5的最短路径是:0->1->5,最短距离是:9
0到6的最短路径是:0->3->4->6,最短距离是:8

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值