当前位置:   article > 正文

无权图的最短路径

无权图

无权图的最短路径

请添加图片描述

Approach:

  • 一种解决方案是使用Bellman-Ford算法在 O(VE) 时间内求解。
  • 如果没有负权重环的话,那么可以使用Dijkstra 算法在 O(E + VLogV) 时间内求解。
  • 由于图是无权的,可以在 O(V + E) 时间内解决这个问题。这个想法是使用广度优先搜索的修改版本,其中我们在进行广度优先搜索时继续存储给定顶点的predecessor。即使图中存在负权重环,该算法也可以完成。
  • 我们首先初始化一个数组 dist[0, 1, …, v-1] ,使得 dist[i] 存储顶点 i源顶点source的距离
  • 数组 pred[0, 1, …, v-1],使得 pred[i] 表示从源开始的广度优先搜索中顶点 i 的直接前驱 immediate predecessor
  • 现在我们在 O(1) 时间内从数组 d 中获得从源顶点source到任何其他顶点的路径长度,并且为了打印从源到任何顶点的路径,我们可以使用数组 p 并且在最坏的情况下将花费 O(V) 时间,因为 V 是数组 P 的大小。所以算法的大部分时间都花在从给定的源顶点source进行广度优先搜索上,我们知道这需要 O(V+E) 时间。因此我们算法的时间复杂度是 O(V+E)

Code:

import java.util.*;

public class ShortestPath {

    static class _1st {

    }


    private static void addEdge(List<List<Integer>> adj, int u, int v) {
        adj.get(u).add(v);
        adj.get(v).add(u);
    }

    /**
     * @param adj  邻接表
     * @param src  源点
     * @param dest 终点
     * @param V    顶点的个数
     */
    public static void printShortestDistance(List<List<Integer>> adj, int src, int dest, int V) {
        int[] dist = new int[V];
        int[] pred = new int[V];
        if (!bfs(adj, src, dest, V, pred, dist)) {
            System.out.println("Given source and destination are not connected");
            return;
        }
        List<Integer> path = new ArrayList<>();
        int cur = dest;
        path.add(cur);
        while (pred[cur] != -1) {
            path.add(pred[cur]);
            cur = pred[cur];
        }
        // Print distance
        System.out.println("Shortest path length is: " + dist[dest]);
        // Print path
        System.out.println("Path is ::");
        for (int i = path.size() - 1; i >= 0; i--) {
            System.out.print(path.get(i) + " ");
        }
    }


    private static boolean bfs(List<List<Integer>> adj, int src, int dest, int V, int[] pred, int[] dist) {
        //存顶点的邻接点将要被访问的
        Queue<Integer> queue = new LinkedList<>();
        //记录当前节点至少被访问过一次
        boolean[] vis = new boolean[V];
        //初始化dist 和 pred 初始距离为MAX 直接前驱节点初始化为-1 不存在的节点
        Arrays.fill(dist, Integer.MAX_VALUE);
        Arrays.fill(pred, -1);
        //src点作为起始点开始转bfs遍历
        vis[src] = true;
        dist[src] = 0;
        queue.offer(src);
        while (!queue.isEmpty()) {
            int u = queue.poll();
            for (int v : adj.get(u)) {
                if (!vis[v]) {//u相邻的节点v,v没有被访问过
                    vis[v] = true;
                    dist[v] = dist[u] + 1;
                    pred[v] = u;
                    queue.offer(v);//当前的节点v的直接前驱节点修改为u
                    if (v == dest) return true;//找到了
                }
            }
        }
        return false;
    }


    public static void main(String args[]) {
        // No of vertices
        int V = 8;
        // Adjacency list for storing which vertices are connected
        List<List<Integer>> adj = new ArrayList<>();
        for (int i = 0; i < V; i++) {
            adj.add(new ArrayList<>());
        }
        // Creating graph given in the above diagram.
        // add_edge function takes adjacency list, source
        // and destination vertex as argument and forms
        // an edge between them.
        addEdge(adj, 0, 1);
        addEdge(adj, 0, 3);
        addEdge(adj, 1, 2);
        addEdge(adj, 3, 4);
        addEdge(adj, 3, 7);
        addEdge(adj, 4, 5);
        addEdge(adj, 4, 6);
        addEdge(adj, 4, 7);
        addEdge(adj, 5, 6);
        addEdge(adj, 6, 7);
        int source = 0, dest = 7;
        printShortestDistance(adj, source, dest, V);
        /**
         * Shortest path length is: 2
         * Path is ::
         * 0 3 7
         */
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104

Reference

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号