1. 程式人生 > 其它 >Dijkstra求最短路(樸素Dijkstra演算法)

Dijkstra求最短路(樸素Dijkstra演算法)

樸素Dijkstra演算法

集合S:存當前已經確定最短距離的點

一、初始化dist[1] = 0, 其餘 dist[i] = 0x3f
二、for i : 0 ~~~ n, 有n個點,每迴圈一次就確定一輪最短距離
1、找到集合s以外的距離最近的點t
2、把t存入s中
3、用t來更新其他距離的點
dist[x] = dist[t] + w(邊權)

849. Dijkstra求最短路 I

給定一個 n
個點 m
條邊的有向圖,圖中可能存在重邊和自環,所有邊權均為正值。

請你求出 1
號點到 n
號點的最短距離,如果無法從 1
號點走到 n
號點,則輸出 −1

輸入格式

第一行包含整數 n
和 m

接下來 m
行每行包含三個整數 x,y,z
,表示存在一條從點 x
到點 y
的有向邊,邊長為 z

輸出格式

輸出一個整數,表示 1
號點到 n
號點的最短距離。

如果路徑不存在,則輸出 −1

資料範圍

1≤n≤500
1≤m≤105

圖中涉及邊長均不超過10000。

輸入樣例:

3 3
1 2 2
2 3 1
1 3 4

輸出樣例:

3

程式碼實現:

#include <bits/stdc++.h>
using namespace std;

const int N = 510;

int g[N][N];    //鄰接表來存有向圖的邊長
int dist[N];
bool st[N];     //判斷這個點是否已經被確定為最短距離,即集合S
int m, n;

int Dijkstra(){
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    for(int i = 1; i <= n; i ++){  //有n個點,要進行n次迭代,每迭代一次就可以確定一個輪最短距離
        int t = -1;  // t表示正在訪問的點
        for(int j = 1; j <= n; j ++){
            if(!st[j] && (t == -1 || dist[t] > dist[j])){   //dist[t] > dist[j]表示t不是最短距離,所以讓t = j
                t = j;      //找到未訪問過且距離最短的點
            }
        }
        
        st[t] = true;
        
        for(int j = 1; j <= n; j ++){
            dist[j] = min(dist[j], dist[t] + g[t][j]);   //取1號點到j號點距離與1到t再到j的最短距離
        }
    }
    if(dist[n] == 0x3f3f3f3f) return -1;
    else return dist[n];
}

int main(){
    cin >> n >> m;
    memset(g, 0x3f, sizeof g);
    int x, y, z;
    for(int i = 0; i < m; i ++){
        cin >> x >> y >> z;
        g[x][y] = min(g[x][y], z);  //有可能存在重邊,所以只要取最短的邊就好
    }
    cout << Dijkstra() << endl;
    return 0;
}