图的最短路径和最小生成树算法

一. 最短路径

单源最短路径问题:给定一个图G = ( V , E ) ,求源结点s ∈ V 到图中每个结点v ∈ V的最短路径。
 

1.dijkstra算法

Dijkstra算法就适用于解决带权重的有向图上的单源最短路径问题,同时算法要求图中所有边的权重非负
针对一个带权有向图G,将所有结点分为两组S和Q,S是已经确定最短路径的结点集合,在初始时为空(初始时就可以将源节点s放入,毕竟源节点到自己的代价是0),Q 为其余未确定最短路径的结点集合,每次从Q中找出一个起点到该结点代价最小的结点u ,将u 从Q 中移出,并放入S 中,对u 的每一个相邻结点v 进行松弛操作。松弛即对每一个相邻结点v ,判断源节点s到结点u 的代价与u 到v 的代价之和是否比原来s 到v 的代价更小,若代价比原来小则要将s 到v 的代价更新为s 到u 与u 到v 的代价之和,否则维持原样。(即以以u为拓展点, 去调整更新相邻的未拓展点与源点之间的最短路径), 如此一直循环直至集合Q 为空,即所有节点都已经查找过一遍并确定了最短路径,至于一些起点到达不了的结点在算法循环后其代价仍为初始设定的值,不发生变化。Dijkstra算法每次都是选择V-S中最小的路径节点来进行更新,并加入S中,所以该算法使用的是贪心策略
 


import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Dijkstra {

    public static void main(String[] args) {
        //图用list[]数组表示, list[i] = {......}, i为出点, 的边
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        //用邻接矩阵
        int[][] matrix = new int[n][n];
        int m = scanner.nextInt();//m条边
        for (int i = 0; i < n; i++) {
            Arrays.fill(matrix[i], 0x3f3f3f3f);
        }
        for (int i = 0; i < n; i++) {
            matrix[i][i] = 0;
        }
        for (int i = 0; i < m; i++) {
            int v = scanner.nextInt();
            int j = scanner.nextInt();
            matrix[v][j] = matrix[j][v] = scanner.nextInt();
        }
        int[] dp = getMinDistance(matrix);
        System.out.println(Arrays.toString(dp));

    }

    /**
     * 源点即起始点默认为0
     * 图的节点是0 到 n - 1
     *
     * @param matrix
     * @return
     */
    public static int[] getMinDistance(int[][] matrix) {
        int n = matrix.length;
        int[] dp = new int[n];
        boolean[] visited = new boolean[n];
//visited数组判断当前顶点是否拓展过了
        PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[1] - o2[1];
            }
        });
        //优先级队列加入的二元组,第一个元素是入点, 
        //第二点是边的大小,小根堆用来找离源点最近并且还没有拓展的点
        visited[0] = true;
        for (int j = 1; j < n; j++) {
            dp[j] = matrix[0][j];
            queue.add(new int[]{j, dp[j]});
        }
        i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨落寒山意

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值