最短路徑問題——學習筆記
(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%的可能性吧。
在這裏,還祝要省選的大佬們加油(怎麽扯到這上面來了。。)!
最短路徑問題——學習筆記