Dijkstra求最短路(樸素and堆優化)

2021-10-04 19:51:30 字數 2089 閱讀 4653

題目來自acwing

題目描述:

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

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

輸入格式

第一行包含整數n和m。

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

輸出格式

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

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

資料範圍

1≤n≤500,

1≤m≤10^5,

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

輸入樣例:

3 3

1 2 2

2 3 1

1 3 4

輸出樣例:3

時間複雜度:

dijkstra: o(n^2);

題目分析:

樸素dijkstra的方法很直觀,每次遍歷下所有的邊,找到點集外可加入點集的距離最小的點,加入到點集(點集中的點應確保是距離最短的)。再嘗試更新下新加入的點附近的點的距離。每次執行下找最短邊的操作時間複雜度是o(n),最壞情況下終點在最後才會被加入到點集,所以過程會被重複n次,故樸素的dijkstra演算法的時間複雜度為o(n^2)。

**如下:

#include

#include

using

namespace std;

const

int maxn =

510;

int n, m;

int g[maxn]

[maxn]

, d[maxn]

;bool vis[maxn]

;int

dijkstra()

vis[t]

=true

;for

(int j =

1;j <= n;j++)}

if(d[n]

==0x3f

)return-1

;return d[n];}

intmain()

cout <<

dijkstra()

<< endl;

return0;

}

對於稀疏圖問題,樸素dijkstra往往很難取得好結果,因此需要加以優化。我們利用優先佇列,實現堆優化的dijkstra。

**如下

來自

1 #include 

2 #include

3 #include

4 #include

5using

namespace std;

6int n,m,s;

7int head[

100001

],dis[

100001

],cnt;

8bool vis[

100001];

9struct qwqedge[

200001];

13void

add(

int u,

int v,

int w)

1423

struct node29}

;30 priority_queue q;

31int

main()

3240

for(

int i=

1;i<=n;i++

)41 dis[i]

=2147483647

;42 dis[s]=0

;43 q.

push

(node);

44while

(!q.

empty()

)45);

57}58}

59}60for

(int i=

1;i<=n;i++)61

printf

("%d "

,dis[i]);

62return0;

63}

Dijkstra演算法求最短路 樸素版

圖論中求最短路的演算法有很多,這裡使用一道模板題來介紹可以求單源最短路的dijkstra演算法 acwing 849.dijkstra求最短路 i 求乙個源點到 除了這個點之外其他所有的點 的最短距離,不需要記錄每條路徑 這題一直困惑著我的是,為什麼一開始找的最小的最短距離就是確定的最短距離?想了好...

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

給定乙個n個點m條邊的有向圖,圖中可能存在重邊和自環,所有邊權均為正值。請你求出1號點到n號點的最短距離,如果無法從1號點走到n號點,則輸出 1。輸入格式 第一行包含整數n和m。接下來m行每行包含三個整數x,y,z,表示存在一條從點x到點y的有向邊,邊長為z。輸出格式 輸出乙個整數,表示1號點到n號...

Dijkstra求最短路

題目鏈結 給定乙個n個點m條邊的有向圖,圖中可能存在重邊和自環,所有邊權均為正值。請你求出1號點到n號點的最短距離,如果無法從1號點走到n號點,則輸出 1。輸入格式 第一行包含整數n和m。接下來m行每行包含三個整數x,y,z,表示存在一條從點x到點y的有向邊,邊長為z。輸出格式 輸出乙個整數,表示1...