美文网首页死磕算法程序员
无向图最短路径问题

无向图最短路径问题

作者: 9c0ddf06559c | 来源:发表于2017-09-27 22:46 被阅读165次

    题目:无向图G有N个结点(1<N<=1000)及一些边,每一条边上带有正的权重值。 找到结点1到结点N的最短路径,或者输出不存在这样的路径。

    • 解决思路:动态规划

    1、首先使用邻接矩阵存储无向图

    2、将找到结点1到节点N的最短路径分解成结点1到节点i的最短路径(1<i<节点数)

    3、对于每一个未计算的结点i,考虑已经计算过的当前最短路径端点choice,如果结点i和结点j直接有边,则计算从结点choice到未计算结点的最短路径

    d[i]=min{A[i][j]+A[j]}

    源码

    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Scanner;
    import java.lang.Integer;
    import java.util.Set;
    
    public class NoPointerChart {
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            int V = in.nextInt();   //输入点数
            int E = in.nextInt();   //输入边数
    
            int[][] A = new int[V][V];
    
            for (int i = 0; i < V; i++) {   //初始化所有边为无穷大
                for (int j = 0; j < V; j++) {
                    A[i][j] = Integer.MAX_VALUE;
                }
            }
            for (int i = 0; i < E; i++) {   //输入每一条边
                int j = in.nextInt();
                int k = in.nextInt();
                int v = in.nextInt();
                A[j - 1][k - 1] = v;
                A[k - 1][j - 1] = v;
            }
    
            Set<Integer> unVisited = new HashSet<>(V);  //记录未访问节点
            Set<Integer> visitied = new HashSet<>(V); //记录已经访问的节点
            int[] d = new int[V];
            for (int i = 1; i < V; i++) {   //初始化最优解都为无限大
                unVisited.add(i);
                d[i] = Integer.MAX_VALUE;
            }
            visitied.add(0);
            d[0] = 0;
    
            int choice = 0;  //中间节点下标,每次选出当前结点到所有可达未标记结点的最短路径端点
            while (unVisited.size() > 0) {   //当仍然有未标记结点的时候 
                int tempMin = Integer.MAX_VALUE;  //记录从中间节点到所有可达结点中的最小值(最短路径)
                int tempMinI = -1;  //记录最短路径的端点下标
                Iterator<Integer> iti = unVisited.iterator();
                while (iti.hasNext()) {  //对于所有未标记的结点
                    int i = iti.next();
                    if (A[choice][i] != Integer.MAX_VALUE) {   //如果中间结点到此未标记结点有边
                        if(d[i]>A[choice][i] + d[choice])   //计算中间结点到当前结点的最短路径
                            d[i] = A[choice][i] + d[choice];
                        if (d[i] < tempMin) {   //计算当前结点到所有可达未标记结点的最短路径
                            tempMin = d[i]; 
                            tempMinI = i;
                        }
    
                    }
                }
                unVisited.remove(tempMinI);visitied.add(tempMinI);  //将当前结点记录未已经标记
                choice = tempMinI; //重新定位中间结点
            }
    
            System.out.println(d[V-1]);
        }
    //测试用例 第一行输入结点数V和边数E ,以下E行输入每条边的端点和权值
    //6 9
    //1 2 6
    //1 3 3
    //2 3 2
    //2 4 5
    //3 4 3
    //3 5 4
    //4 5 2
    //4 6 3
    //5 6 5
    }
    
    

    参考 http://www.hawstein.com/posts/dp-novice-to-advanced.html
    参考 http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html

    相关文章

      网友评论

        本文标题:无向图最短路径问题

        本文链接:https://www.haomeiwen.com/subject/nkhwsxtx.html