模板 單源最短路徑

2022-05-01 06:00:08 字數 3609 閱讀 3392

如題,給出乙個有向圖,請輸出從某一點出發到所有點的最短路徑長度。

輸入格式:

第一行包含三個整數n、m、s,分別表示點的個數、有向邊的個數、出發點的編號。

接下來m行每行包含三個整數fi、gi、wi,分別表示第i條有向邊的出發點、目標點和長度。

輸出格式:

一行,包含n個用空格分隔的整數,其中第i個整數表示從點s出發到點i的最短路徑長度(若s=i則最短路徑長度為0,若從點s無法到達點i,則最短路徑長度為2147483647)

輸入樣例#1:

4 6 1

1 2 2

2 3 2

2 4 1

1 3 5

3 4 3

1 4 4

輸出樣例#1:

0 2 4 3
時空限制:1000ms,128m

資料規模:

對於20%的資料:n<=5,m<=15

對於40%的資料:n<=100,m<=10000

對於70%的資料:n<=1000,m<=100000

對於100%的資料:n<=10000,m<=500000

樣例說明:

思路:spfa or dijkstra

此題是有向邊!!!(然而我並沒有被這裡坑)

初始化最短路徑表;

源點入隊;

取出隊首點;

列舉取出點的邊;

如果能鬆弛,就鬆弛,並把被鬆弛的點加入佇列;

如此迴圈直到隊列為空。

另外,根據2183ms的親測,使用優先佇列應該沒有明顯優化效果(可能更穩定了,我不太懂)。

初始化最短路徑表;

源點標記;

用源點的邊鬆弛;

尋找距離最短的未被標記的點;

用這個點的邊鬆弛;

如此迴圈n-1次。

雖然dijkstra大部分時候不如spfa快,但理論是dijkstra更穩定。

769ms的spfa:

1 #include2

int n,m,s,v[10010];3

inta,b,c;

4int q[500010

],head,tail;

5int h[10010

],hs;

6struct edgee[500010

];7 inline bool rel(long

long x,long

long y,long

long z)

8int

main();

14 h[a]=hs;15}

16 q[head++]=s;

17while(head>tail)24}

25}26for(int i=1;i<=n;i++) printf("

%d "

,v[i]);

27return0;

28 }

1 #include2 #include3

using

namespace

std;

4int n,m,s,v[10010];5

inta,b,c;

6 priority_queue q;

7int h[10010

],hs;

8struct edgee[500010

];9 inline bool rel(long

long x,long

long y,long

long z)

10int

main();

16 h[a]=hs;17}

18q.push(s);

19while(!q.empty())27}

28}29for(int i=1;i<=n;i++) printf("

%d "

,v[i]);

30return0;

31 }

2183ms優先佇列(stl)優化的spfa

2305ms的dijkstra:

1 #include2

int n,m,s,w[10010];3

inta,b,c;

4bool v[10010];5

int h[10010

],hs;

6struct edgee[500010

];7 inline bool rel(long

long x,long

long y,long

long z)

8int

main();

14 h[a]=hs;15}

16 v[s]=1;17

for(int i=h[s];i;i=e[i].n) if(rel(w[e[i].s],0,e[i].v)) w[e[i].s]=e[i].v;

18for(int k=1;k)

24for(int i=1;i<=n;i++) printf("

%d "

,w[i]);

25return0;

26 }

20分的堆優化的dijkstra(恕我無能):

1 #include2

#define ll long long

3#define maxn 10010

4#define maxm 500010

5#define inf 2147483647

6int n,m,q,w[maxn],in

[maxn];

7int

a,b,c,l,r;

8int

p[maxn],ps,top;

9bool

v[maxn];

10struct edgee[maxm];

11struct heaph[maxm];

12 inline void add(int x,int y,int z),p[x]=ps;}

13 inline ll min(ll x,ll y,ll z)

14void swap(int x,int y,int xx,int

yy);

16 h[x]=(heap);

17 h[y]=(heap);

18in[xx]=y;in[yy]=x;19}

20void push(int x,int y,int

z),in[x]=z;

22while(in[x]>1)26

}27intpop();

30int x=h[1

].s,z;

31in[h[1].s]=1;32

while(in[x]<=top)

39return

ret;40}

41int

main()

48for(int k=0;k)58}

59}60for(int i=1;i<=n;i++) printf("

%d "

,w[i]);

61return0;

62 }

感覺洛谷的板子題都好厲害。

單源最短路徑 模板 dijkstra

p4779 模板 單源最短路徑 標準版 原題鏈結 鏈式前向星 題目描述 給定乙個 n個點,m條有向邊的帶非負權圖,請你計算從 s 出發,到每個點的距離。資料保證你能從 s 出發到任意點。輸入格式 第一行為三個正整數 n,m,s。第二行起 m 行,每行三個非負整數 ui,vi,wi表示從ui到 vi ...

單源最短路徑

include define max 999 define maxverts 10 typedef struct graph void chushi graph g void dij graph int key,int int int main for i 1 i g.numverts i dij ...

單源最短路徑

最優子結構 最短路徑的子路徑也是最短路徑,動態規劃和貪心演算法的乙個重要指標。環路 一條最短路徑不可能包含環路 1 環路權重為負,如果有一條環路權重為負,則不存在最短路徑 2 環路權重為零,如果包含該環路,則將該環路去掉即可 3 環路權重為正,去掉改環路可以得到更短的路徑,因此不可能是最短路徑 最短...