公告

👇 微信 👇

图片

欢迎私信交流

Skip to content

5-Dijkstra算法 ​

算法思想 ​

算法模板 ​

朴素算法 ​

java
import java.util.*;
public class Main {
    static int N = 510, M = 0x3f3f3f3f;;
    // dist[i]存储(1号点到)i 号点的最短距离
    static int[] dist = new int[N];
    // g[][]存储每条边的长度
    static int[][] g = new int[N][N];
    // st[i]标记(1号点到)i 号点的最短距离是否已经确定
    static boolean[] st = new boolean[N];
    static int n, m;


    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        m = in.nextInt();
        for(int i = 1; i <= n; i ++ ) Arrays.fill(g[i], M);
        Arrays.fill(dist, M);
        
        while(m -- > 0)
        {
            int from = in.nextInt(), to = in.nextInt();
            int weight = in.nextInt();
            
            g[from][to] = Math.min(weight, g[from][to]);
        }
        
        System.out.println(dijkstra());
    }
    

    public static int dijkstra()
    {
		Arrays.fill(dist, M);
        dist[1] = 0;

        for(int i = 0; i < n; i ++ )
        {
            int t = -1;
            // 在未确定最短路径的点中,选择一个距离(1号点)最近的点
            // 首次选择的是1号点自身
            for(int j = 1; j <= n; j ++ )
            {
                if(!st[j] && (t == -1 || dist[j] < dist[t]))
                    t = j;
            }
            
            for(int j = 1; j <= n; j ++)
                dist[j] = Math.min(dist[j], dist[t] + g[t][j]);
            
            st[t] = true;
        }
        
        return (dist[n] == M) ? -1 : dist[n];
    }
}

堆优化算法 ​

java
import java.util.*;

public class Main {
    static int N = 150010, M = 0x3f3f3f3f;
    // 稀疏图使用邻接表
    static int[] e = new int[N],
        ne = new int[N],
        h = new int[N],
        w = new int[N];
    static int[] dist = new int[N];        
    static boolean[] st = new boolean[N];
    static PriorityQueue<Dist> q = new PriorityQueue<Dist>(Comparator.comparing(d -> d.length));
    // idx 代表点的索引(在数组 e, ne, h 当中),
    // 也代表边的索引(在数组 w 当中)
    static int n, m, idx;
    
    
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        m = in.nextInt();
        Arrays.fill(dist, M);
        Arrays.fill(h, -1);
        
        while(m -- > 0)
        {
            int from = in.nextInt(), to = in.nextInt();
            int weight = in.nextInt();
            add(from, to, weight);
        }
        
        System.out.println(dijkstra());
    }
    
    static void add(int u, int x, int weight)
    {
        e[idx] = x;
        w[idx] = weight;
        ne[idx] = h[u];
        h[u] = idx ++;
    }
    
    static int dijkstra()
    {
        dist[1] = 0;
        q.offer(new Dist(1, 0));
        
        while(!q.isEmpty())
        {
            Dist t = q.poll();
            int end = t.end, length = t.length;
            
            if(st[end]) continue;
            st[end] = true;
            
            int p = -1;
            for(int i = h[end]; i != -1; i = ne[i])
            {
                int k = e[i];
                int weight = w[i];
                if(st[k]) continue;
	            // 当最短路径可以缩短时
                if(dist[end] + weight < dist[k])
                {
                    dist[k] = dist[end] + weight;
                    q.offer(new Dist(k, dist[k]));
                }
            }
        }
        
        return dist[n] == M ? -1 : dist[n];
    }
}


class Dist 
{
    // end 代表 end 号点
    // length 代表(局部情况下的)1号点到 end 号点的最短距离
    int end, length;
    public Dist(int end, int length)
    {
        this.end = end;
        this.length = length;
    }
}