算法 - Dijkstra 最短路径

Dijkstra(迪杰斯特拉)算法是典型的最短路径路算法,用于计算一个节点到其他所有节点的最短路径。

由于遍历节点很多,所以 Dijkstra 效率低。

Dijkstra 属于贪心算法总是做出在当前看来是最好的选择)。 

算法步骤  

1  初使时令 S = { V0 },U = { 剩余顶点 },dist[ ] = { V0到各边的距离 } 。

2  从U中选取一个不在S中且距离值最小的顶点V,将W加入S。

3  对U中顶点的距离值dist[ ]进行修改

dist[i] = min( dist[v]+graph[v][i], dist[i] )    

4  重复 (2→3)  n-1次。


CodeDemo

import java.util.*;  
public class Test {  

    final static int MAXN = 100; // 最大顶点数 
    final static int MAXE = 10000000; // 使用Integer.MAX_VALUE有时会溢出
    static Scanner scan = new Scanner(System.in); // 获取控制台输入
    
    public static void main(String[] args) {  
    	/**
    	 * 初始化
    	 */
        int[][] graph = new int[MAXN][MAXN]; // 初始化图的领结矩阵  
        int[] dist = new int[MAXN]; // 记录最短路径  
        boolean[] S = new boolean[MAXN]; // 被访问过的顶点集   
        int n,m;   
        n = scan.nextInt(); // 顶点数 
        m = scan.nextInt(); // 边数 
        Arrays.fill(S, false); // 数组vis全部赋值为false 
        for(int i=0;i<n;i++)      
            for(int j=0;j<n;j++)      
                if(i==j)  
                    graph[i][j] = 0; // 自己和自己的距离为0 
                else  
                    graph[i][j] = MAXE; // 其余边初始化为无穷大 
        int pos1,pos2;  
        for(int i=0;i<m;i++)    { // 记录m条边的权值 
            pos1 = scan.nextInt();   
            pos2 = scan.nextInt();  
            graph[pos1][pos2] = scan.nextInt();  
        }  
        for(int i=0;i<n;i++) // 初始化顶点0到各顶点的距离   
            dist[i] = graph[0][i];  
        S[0] = true; // 顶点0已经被访问
        /**
         * 先找到目前满足最短路径的顶点v:未被访问且dist[]值最小
         * 再更新dist[]:在未被访问的顶点集中取 mim(dist[v]+dist[v][i], dist[i])
         */
        int min; // 记录最小值
        int v = 0; // 记录每次被找到的顶点  
        for(int i=0;i<n-1;i++) { // 每次在未访问顶点集中寻找一个离顶点0距离最短的顶点 ,n-1次可以遍历完所有顶点。 
            min = MAXE; // 初始化 
            for(int j=0;j<n;j++) { // 寻找顶点j  
                if(S[j]!= true && dist[j]<min) { // 寻找dist[]中未被访问的最小值顶点  
                    min = dist[j]; // 记录最小值
                    v = j; // 记录顶点
                }  
            S[v] = true; // 加入已被访问集合   
            }  
            for(int j=0;j<n;j++) { // 算法核心:更新 dist[]  
                if(S[j] != true && dist[j]>dist[v]+graph[v][j]) {   
                    dist[j] = dist[v] + graph[v][j];  
                }  
            }  
        }  
        
        for(int i=0;i<n;i++) {  
            System.out.println("0->"+i+":"+dist[i]);  
        }
        
    }  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值