<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
給定一張有向圖,若對於圖中的某一條邊(x,y,z),有dist[y]≤dist[x]+z成立,則稱該邊滿足三角形不等式。如果所有邊都滿足三角形不等式,則dist陣列就是所求的最短路。
(x,y,z)表示的是一條從 x 出發, 到達 y ,長度為 z 的有向邊。
首先介紹基於迭代的Bellman-Ford演演算法,它的流程如下:
1.掃描所有邊(x,y,z),若dist[y]>dist[x]+z, 則用dist[x]+z更新dist[y]
2.重複上述操作,直到沒有更新操作發生。
Bellman-Ford演演算法的時間複雜度是O(nm)
通過Bellman-Ford演演算法我們可以求解有邊數限制的最短路問題。
初始化 dist 陣列為正無窮, dist[1] = 0
(外重回圈)迴圈 i 從 1 到 n ,遍歷 n 次表示:是不經過超過 i 條邊到達終點的最短距離
(內重回圈)迴圈 i 從 1 到 m, 遍歷 m 條邊,把所有的邊都進行鬆弛操作:
每次取出兩點以及以及連線他們的權重 (a,b,w)
用以下公式更新最短距離: dist[b]=min(dist[b],dist[a]+w)
注意點:
需要把dist陣列進行一個備份,這樣防止每次更新的時候出現串聯
由於存在負權邊,所以 return -1 的條件是dist[n]>0x3f3f3f/2
#include <iostream> #include <cstring> using namespace std; const int N = 510, M = 10010; struct Edge { int a, b, w; }e[M]; // 存下每一條即可 int dist[N]; int back[N]; // 備份陣列放置串聯 int n, m, k; void bellman_ford() { memset(dist, 0x3f, sizeof dist); dist[1] = 0; for(int i = 0; i < k; i ++ ) // 不超過k條邊 { memcpy(back, dist, sizeof back); for(int j = 0; j < m; j ++ ) // 遍歷所有邊 { int a = e[j].a, b = e[j].b, w = e[j].w; dist[b] = min(dist[b], back[a] + w); } } } int main() { cin >> n >> m >> k; for(int i = 0; i < m; i ++ ) { int a, b, w; scanf("%d%d%d", &a, &b, &w); e[i] = {a, b, w}; } bellman_ford(); if(dist[n] > 0x3f3f3f3f / 2) puts("impossible"); else cout << dist[n] << endl; return 0; }
SPFA演演算法在國際上通稱為“佇列優化的“Bellman-Ford演演算法”。
SPFA演演算法的流程如下:
1.建立一個佇列,起初佇列中只含有起點1
2.取出頭結點 x ,掃描它的所有出邊(x,y,z),若dist[y]>dist[x]+z,則使dist[y]用dist[x]+z來更新。同時若y不再佇列中,則將y入隊
在任意時刻,該演演算法的佇列都保持了該拓展的節點。每次入隊都相當於完成了一次 dist 陣列的更新操作,使其滿足三角不等式。一個節點可能會入隊、出隊多次。最終,圖中所有的結點全部收斂到全部滿足三角不等式的狀態。
這個佇列避免了對Bellman-Ford演演算法中不需要拓展的多餘結點的冗餘掃描,在隨機圖上的執行效率O(km)級別,其中 k 是一個很小的常數。
SPFA求最短路
#include <cstring> #include <iostream> #include <algorithm> #include <queue> using namespace std; const int N = 1e6 + 10; int n, m; int h[N], e[N], w[N], ne[N], idx; int dist[N]; bool st[N]; void add(int a, int b, int c) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ; } void spfa() { memset(dist, 0x3f, sizeof dist); queue<int> q; dist[1] = 0; st[1] = true; q.push(1); while(q.size()) { int t = q.front(); q.pop(); st[t] = false; for(int i = h[t]; ~i; i = ne[i]) { int j = e[i]; if(dist[j] > dist[t] + w[i]) { dist[j] = dist[t] + w[i]; if(!st[j]) { q.push(j); st[j] = true; } } } } } int main() { scanf("%d%d", &n, &m); memset(h, -1, sizeof h); while (m -- ) { int a, b, c; scanf("%d%d%d", &a, &b, &c); add(a, b, c); } spfa(); if(dist[n] == 0x3f3f3f3f) puts("impossible"); else printf("%d",dist[n]); return 0; }
以上就是C++圖論之Bellman-Ford演演算法和SPFA演演算法的實現的詳細內容,更多關於C++ Bellman-Ford SPFA演演算法的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45