package org.kne.cloud.network.srv6;
public class DijstraAlgorithm {
    //不能设置为Integer.MAX_VALUE，否则两个Integer.MAX_VALUE相加会溢出导致出现负权
    public static int M = 100000;
    //定义七个顶点
    private static char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};

    public static void main(String[] args) {

        //初始化邻接矩阵
        int[][] matrix = new int[vertex.length][vertex.length];
        matrix[0] = new int[]{M, 5, 7, M, M, M, 2};
        matrix[1] = new int[]{5, M, M, 9, M, M, 3};
        matrix[2] = new int[]{7, M, M, M, 8, M, M};
        matrix[3] = new int[]{M, 9, M, M, M, 4, M};
        matrix[4] = new int[]{M, M, 8, M, M, 5, 4};
        matrix[5] = new int[]{M, M, M, 4, 5, M, 6};
        matrix[6] = new int[]{2, 3, M, M, 4, 6, M};

        //调用dijstra算法计算最短路径
        dijstra(matrix, 0);
    }

    /**
     * @param matrix：邻接矩阵
     * @param 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] = vertex[source] + "->" + vertex[i];
        }

        //初始化起点，将起点放入S
        shortest[source] = 0;
        visited[source] = 1;

        for (int i = 1; i < matrix.length; i++) {       //i从1开始，因为起点已经加入S了
            int min = M;
            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] + "->" + vertex[m];
                }
            }
        }

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