對於乙個邊權為正的圖,我們可以利用dijkstra演算法求出單源最短路徑(sssp),對於常規的dijkstra演算法,其複雜度為 o(n
2)
o(n^2)
o(n2
) ,顯然在 n
nn 較大的時候,可能導致耗時過長,通過優化我們可以獲得一種更加快速的dijkstra演算法,時間複雜度為 o(m
logn
)o(mlogn)
o(mlog
n)。在傳統的dijkstra演算法中,在d[n]
中尋找未被訪問且最小的d[i]
採用的是遍歷陣列的方式,這樣會導致時間的複雜度變高,既然是輸出最小的權值邊,那麼我們可以用stl中的priority_queue
的優先佇列來實現這一操作,可以實現加速。當然,為了實現這一操作,我們儲存圖也不再利用簡單的鄰接矩陣,而是先儲存邊的資料,再將邊的資料儲存到vector
陣列中,有點像鄰接表,但不是鄰接表。
**源於《演算法競賽入門經典(第2版)》(紫書)
看了上述的**,不妨來做道題試試。struct edge};
struct heapnode};
struct dijkstra
void
addedge
(int from
, int to, int dist)
void
dijkstra
(int s));
while(!
q.empty()
));}
}}}}
;
題目:j-free:
題意:給定乙個圖,有 n
nn 個點, m
mm 個邊,每個邊的權值為 l
ll, 你可以讓圖上至多 k
kk 個邊的權值變為 0
00,請問,在這樣的操作過後,從頂點 s
ss 到頂點 t
tt 的最短路徑是多少。
題解:在了解了上述的關於堆優化的dijkstra演算法過後,對於解這題很有幫助。由於到點的距離與 k
kk 有了關係,我們不能再用原先的一維陣列d[n]
來儲存到各個點的距離的最短路徑,而是要開乙個二維陣列dis[n][m]
,其中dis[i][j]
表示從源點到頂點 i
ii 在使 j
jj 個邊的權值變成 0
00 的情況下的最短路徑。這樣我們就很容易地可以獲得答案了。那麼要如何建立這個二維陣列dis[n][m]
呢,在原先的dijkrstra演算法中,我們向q中push乙個heapnode的條件是d[e.to] > d[u] + e.dist
,在這裡由於多了乙個考慮因素 k
kk ,所以我們的heapnode中要增加乙個變數ktime
來表示刪掉權值邊的個數。同時,push的判定條件,也由原來的乙個變成了兩個,乙個是在ktime不變的情況下是否push,另乙個是在ktime+1的情況下是否push。這樣就可以完美地構建出二維陣列的dis[n][m]
了。最後在尋找 ans
ansan
s 時,只需要遍歷dis[t]
即可。
**:
#include .h>
using namespace std;
const int maxn =
1e3+5;
typedef long long ll;
#define inf
1e9+
5int n, m,s,
t, k;
ll dis[maxn]
[maxn]
;struct edge};
struct heapnode};
struct dijkstra
void
addedge
(int from
, int to, int dist)
void
dijkstra
(int s));
while(!
q.empty()
));}
if(ktime[ktime]
[ktime+1]
));}
}}}}
;int main()
dij.
dijkstra(s
);ll ans =
inf;
for(int i =
0; i <= k; i++
)printf
("%lld"
, ans)
;return0;
}
dij演算法堆優化 Floyd演算法
乙個號稱只有5行 的演算法,由1978年圖靈獎獲得者 史丹福大學電腦科學系教授羅伯特 弗洛伊德命名。該演算法有於求乙個帶權有向圖 wighted directed graph 的任意兩點的最短距離的演算法,運用了動態規劃的思想,演算法的時間複雜度為o v 3 空間複雜度o v 2 其核心思想是,在兩...
ACM特定演算法的卡常優化
今天做一道樹鏈剖分的題目,發現被卡常了,於是修改了很久,列印出執行時間,發現有這3個地方對常數的影響特比大 1.i o 用輸入外掛程式所消耗的時間大概是用關同步 tie的cin的一半 測試 輸入了1e5 3的資料,cin用了0.2s,in用了0.1s 2.vector 鏈式前向星 不得不說cache...
廣度優先演算法,深度優先演算法和DijKstra演算法
我們經常會碰到最短路徑問題,而最短路徑問題的解決方法多種多樣,廣度優先搜尋 bfs 深度優先搜尋 dfs 和dijkstra演算法貌似都能解決這個問題,這裡就簡單介紹一下這些演算法,分析一下它們的適用範圍。一 原理剖析 1 廣度優先搜尋 bfs 廣度優先搜尋依賴的是佇列解決問題。佇列中的每乙個節點需...