穿越空間的限制,走最短的路找到你
u->v之間的最短路滿足以下限制: 對任意k ∈ g(v,e) 有 dist u,v <= dis u,k + dis k,j
關鍵操作-鬆弛
void relax(int i,int j,int k)
floyd
void floyd()
複雜度o(v^3)可處理負環
拓展把所有邊存成負的可以作為最長路。
void bellman_ford(int s)
}}}
複雜度o(k*e)可處理負環(乙個點入隊次數超過n次) 加上slf
和lll
優化後k很小
void dijikstra(int s)
}}
複雜度o(v^2+e)不可處理負環 可用heap,線段樹等優化到o((v+e)lo**),o(vlo**+e)
存逆圖跑單源最短路即可。
對於乙個dag可以得知它的拓撲序,從而通過dp解決問題
queueq;
int dag_shortest_path()
} ans=inf;
for(int i=1;i<=topo[0];++i)
ans=min(ans,dis[u]);
} return ans;
}
複雜度o(v+e)
首選自然是spfa,好打而且跑得快,而且幾乎沒有考試喪心病狂到卡spfa。 如果實在不放心,就選擇priority_queue+dijikstra吧。
如果點數很小而且要求任意兩個點之間的距離,那麼就floyd吧 否則首選是dijikstra+priority_queue,至於為什麼不選擇樸素dijikstra,因為它比較長。
spfa
dag最短/最長鏈
spfa和priority_queue dijikstra比較實用,一般會這兩個就行了。 最好寫的是floyd。 dag最短/最長鏈在某些題目中很重要。 bellman-ford沒卵用。
--來自xb神犇
最短路總結
寫個部落格記錄一下最短路的幾種演算法,盡量做最正確的解答,減少大家的疑惑,網上有好多講的都抄來抄去,還有好多講的都是錯誤的。熟悉的最短路演算法就幾種 bellman ford,dijkstra,spfa,floyd,下面針對這幾個演算法具體解析一下。首先說明一點,就是關於負環的問題。bellman ...
最短路總結
首先是dij演算法,這是我第乙個掌握的最短路演算法!再來是bellman ford演算法,這個演算法比較容易理解,而且考慮到了負環的存在。記住,它對圖中的邊進行了 v 1次操作!首先,對d進行初始化 還有乙個spfa演算法 摘錄於學長空間 設立乙個先進先出的佇列用來儲存待優化的結點,優化時每次取出隊...
最短路總結
本來以為自己不用總結 回頭再看這幾種演算法都忘光了qaq 如果存在乙個環 從某個點出發又回到自己的路徑 而且這個環上所有權值之和是負數,那這就是乙個負權環,也叫負權迴路 floyd演算法適合解決多源最短路 複雜度最高 解決負邊 負權 但不能解決負環 void floyd floyd 最後map i ...