1. 程式人生 > >最短路徑問題——學習筆記

最短路徑問題——學習筆記

入隊 單元最短路徑 單源最短路 完成 true 實現 som 不可 單源最短路徑

(1)Dijkstra算法

1.算法時間復雜度:O(N2)

2.算法特點:

該算法是用來計算從一個點到其他所有點的最短路徑算法,也是一種單源最短路徑算法。該算法不能處理存在負邊權的情況。

3.算法描述

起點:s dis[v]:s到v的最短路徑 pre[v]:v的前驅節點

初始化:dis[v]=∞(v≠s) dis[s]=0 pre[s]=0

for(int i=1; i<=n; i++){

  //在沒有被訪問過的點中找一個頂點u使得dis[u]最小。

  //u標記為已確定的最短路徑。

  //找與u相連的每一個未確定的最短路徑的頂點v。

if(dis[u]+w[u][v]<dis[v]) {
    dis[v]
=dis[u]+w[u][v]; pre[v]=u; }

}

(2)SPFA算法

1.算法時間復雜度:O(kE)。E=邊數,K=常數,平均值=2。

2.something

SPFA是Bellman-Ford算法的一種隊列實現,減少了不必要的一些計算。可以說是Bellman-Ford+隊列優化。形式上與BFS極其相似的一種單元最短路徑算法。

但是在BFS中,只要有個點出隊列,就不可能再一次進隊列了。但是SPFA不同。在SPFA中,一個點在出隊列之後有可能又被放入了隊列。

3.算法實現

dis[i]:從起點s到i的最短路徑 w[i][j]:鏈接i和j的邊長度 pre[v]:前趨

team[n]:隊列 and head=頭指針,tail=尾指針

初始化:dis[s]=0,dis[v]=∞(v≠s),將exist數組用memset函數全部賦為false。

//起點入隊
do{
    //頭指針下移1位,取出指向的點u
    exist[u]=false
    //for與u相連的所有點v (不要枚舉所有點,如果那樣好像就成了BMF了(好像不是這樣啊。。最起碼要慢不少))
    if(dis[v]>dis[u]+w[u][v]){
        dis[v]=dis[u]+w[u][v];
        pre[v]=u;
        if(!exist[v]){
            
//尾指針下移1位,v入隊列 exist[v]=true; } } }while(head<tail);

下面是雜談:

這幾天在信競老師那裏學最短路徑算法。老師說最後學弗洛伊德。。BMF算法由於有SPFA的存在,就不再說了。

這幾天在學校的OJand洛谷上寫最短路徑和一些圖論題和一些水題。

等過一段時間我上了弗洛伊德算法後在繼續完成剩余的部分吧。

3月25號就市賽了,爭取進市隊。自己預計了一下,大概有35%的可能性吧。

在這裏,還祝要省選的大佬們加油(怎麽扯到這上面來了。。)!

最短路徑問題——學習筆記