單源最短路徑(Dijkstra)

2021-10-09 17:22:01 字數 1950 閱讀 4420

給定乙個 n 個點,m 條有向邊的帶非負權圖,請你計算從 s 出發,到每個點的距離。

輸入格式

第一行為三個正整數 n,m,s。第二行起 m 行,每行三個非負整數 ui,vi,wi,表示從 ui 到 vi 有一條權值為 wi 的有向邊。

輸出格式

輸出一行 n 個空格分隔的非負整數,表示 s 到每個點的距離。

輸入14 6 1

1 2 2

2 3 2

2 4 1

1 3 5

3 4 3

1 4 4

輸出10 2 4 3

說明/提示

1 ≤ n ≤ 105

1 ≤ m ≤ 2×105

s = 1

1 ≤ ui , vi ≤ n

0 ≤ wi ≤ 109

0 ≤ ∑ wi ≤ 109 思路

標準的dijkstra,不解釋(然而第一次做時不會用優先佇列,所以爆零了)

值得一提的是,樸素dijkstra的時間複雜度好像是 o( n2 ) ,而優先佇列優化的時間複雜度好像是 o( m log m ),在選擇優不優化時看清資料範圍(即 m = n2 時,比如某道最小生成樹題,以後應該會發)。

**是以前寫的,所以碼風和變數名不忍直視,甚至還出現了一些我自己都看不懂的蜜汁操作(

不過由於情懷問題還是發上來吧(其實是因為不想重新寫一遍),以後有時間再重寫。

**o( n2 ):

#include

#include

#include

#include

using

namespace std;

int n,m,s,dis[

10001

],first[

10001

],next[

500001];

bool vis[

10001];

struct st

a[500001];

intmain()

}int p=first[s]

;while

(p!=0)

dis[s]=0

; dis[0]

=2147483647

; vis[s]

=true

;int sum;

for(

int i=

2;i<=n;i++)}

for(

int i=

1;i<=n;i++

)return0;

}

o( m log m ):
#include

#include

#include

#include

using

namespace std;

#define n 999999999999999999

long

long n,m,s,fi[

100005

],ne[

200005

],dis[

100005

],t;

bool vis[

100005];

struct st

maap[

200005];

struct no

}a;priority_queue q;

intmain()

a.f=s;

a.jz=0;

dis[s]=0

; q.

push

(a);

while

(!q.

empty()

) t=ne[t];}

}for

(int i=

1;i<=n;i++

)printf

("%d "

,dis[i]);

return0;

}

Dijkstra 單源最短路徑

演算法思想 輔助陣列dis i 表示當前源頂點到i的最短路徑。dis i 在程式未結束前,類似於動態規劃,可更新以取得最小值 陣列path用來記錄路徑 首先初始化令dis i 為edge v0 i v0為源頂點 然後選擇離源頂點最小的路徑,加入到構造最短路徑的點集合中,然後看是否可以更新dis i ...

Dijkstra 單源最短路徑

演算法思想 輔助陣列dis i 表示當前源頂點到i的最短路徑。dis i 在程式未結束前,類似於動態規劃,可更新以取得最小值 陣列path用來記錄路徑 首先初始化令dis i 為edge v0 i v0為源頂點 然後選擇離源頂點最小的路徑,加入到構造最短路徑的點集合中,然後看是否可以更新dis i ...

Dijkstra單源最短路徑

dijkstra單源最短路徑 給定乙個帶權有向圖g v,e 其中每條邊的權是乙個非負實數。另外,還給定 v 中的乙個頂點,稱為源。現在我們要計算從源到所有其他各頂點的最短路徑長度。這裡的長度是指路上各邊權之和。這個問題通常稱為單源最短路徑問題。下面給出兩個計算單源最短路徑的模板。dijkstra 簡...