spfa判定負環

2021-10-06 19:32:19 字數 1096 閱讀 5704

我們用陣列記錄每個結點的最短路徑估計值,用鄰接表來儲存圖g。

採取的方法是動態逼近法:

1、設立乙個先進先出的佇列用來儲存待優化的結點。

2、優化時每次取出隊首結點u,並且用u點當前的最短路徑估計值對離開u點所指向的結點v進行鬆弛操作,如果v點的最短路徑估計值有所調整,且v點不在當前的佇列中,就將v點放入隊尾。

3、這樣不斷從佇列中取出結點來進行鬆弛操作,直至佇列空為止

因為這個反覆鬆弛的過程使得spfa演算法可以求帶有負權邊的最短路問題,這是與dijkstra的主要區別

如下圖所示的乙個圖,我們可以輕易發現2,3,4三個節點之間的邊組成了乙個負環,在spfa演算法的迭代中,如果出現了負環會陷入死迴圈,給乙個通俗的解釋,要求節點1到節點5的最短距離,如果是1--2--3--5的路線,那麼距離是10,顯然1--2--3--4--2--3--5 這條路線距離變成了8,所以,為了達到最短路,會在2,3,4之間永遠迴圈下去,所以這個性質就是用來判斷最短路的依據

如果不存在負環的話,每個節點可以通過其他節點作為中間節點然後再到達該節點來進行鬆弛,所以每個節點最多鬆弛n次,因此只要某個節點進入佇列了超過了n次,那必定存在負環!

以該題為例,這是乙個最簡單的判負環問題:

#include#include#include#includeusing namespace std;

const int n=10010;

int h[n],e[n],ne[n],idx,w[n];

int dist[n];

bool st[n];

int n,m;

int cnt[n];

void add(int a,int b,int c)

int spfa()}}

}return 0;

}

int main()

int t=spfa();

if(t==1)cout<

else cout<

return 0;

}

SPFA判斷負環

說明一下,這個例題用下面的方法是過不了的,只能過掉25分因為資料加強了,而我不會寫bfs版spfa判負環 但是我覺得會dfs版的就行了,反正對於隨機資料dfs版的絕對吊打bfs版的 只不過這道題的資料不是隨機的,是有人惡意新增的 我們利用dfs強行進行鬆弛操作 我感覺已經不能叫他spfa了 如果在一...

模板 負環(spfa)

暴力列舉 spfa bellman ford 奇怪的貪心 超神搜尋 輸入格式 第一行乙個正整數t表示資料組數,對於每組資料 第一行兩個正整數n m,表示圖有n個頂點,m條邊 接下來m行,每行三個整數a b w,表示a b有一條權值為w的邊 若w 0則為單向,否則雙向 輸出格式 共t行。對於每組資料,...

模板 負環判定

存在負環,即 執行 spfa 演算法時,乙個點被更新了 n 次或 n 次以上,那麼一定存在負環。由於無向圖任意兩點間的簡單路徑經過的邊數均小於 n,且 b f 演算法在第 i 輪迭代結束時可以求得經過不超過 i 條邊得到的單源最短路。因此,在 n 1 次迭代時一定可以將所有點的最短路均求出。更高效率...