筆記 最短路 SPFA演算法

2022-04-08 01:19:28 字數 1706 閱讀 2269

##演算法功能

找最短路(最長路?)

##演算法思想

用乙個節點k更新節點i到節點j的最短路

##鄰接鍊錶儲存

基礎而高效的圖的儲存方式

存的是單向邊(無向邊可以看成兩條有向邊)

##實現

維護節點i到源點s的最小值d[i]

用佇列實現

維護佇列z,

用visit記錄乙個點是否在佇列

從源點開始進佇列,每次彈出隊頭元素x,(標記visit[x]=0)

用它的最短路d[x]將與它相連的節點y的最短路d[y]更新

如果y不在佇列(visit[y]==0),讓y入隊,記錄(visit[y]=1)

直到隊列為空,所有節點的d都已維護好

##判斷負環

若圖中存在負環,則更新時一定不斷地讓負環上的節點入隊,負環上的點一定會無數次入隊,最終死迴圈

所以我們記錄乙個點入隊的次數sum,sum[i]在每次i入隊時++,如果sum[i]賊大,賊大,證明有負環

賊大到多大呢?賊大到2*m(m是邊數)就肯定死迴圈了

反正就是不能比2*m大(一共m條邊,假設都與節點i相連,則i最多入隊m次(當然不可能所有邊都讓i走一遍)(老師讓sum[i]和m*2比較,不知道為啥那麼大

1 #include 2 #include 3 #include 4 #include 

5 #include 6 #include 7 #include 8

#define n 100010

9#define m 100010

10//

複雜度上限m*n

11//

n個點,每個如m次

1213

//正常nlogn

1415

//網格圖賊慢

16using

namespace

std;

1718 queue z;

19int

d[n],len,visit[n],n,m;

2021

//採用結構體存圖

22struct

edge

23a[m];

26//

鄰接鍊錶儲存

27int

first[m];

28void ins(int x,int y,int

k)29

37int

sum[n];

3839

intmain()

4050

ints;

51 cin>>s;//

源點 52

z.push(s);

53 visit[s]=1

;54 d[s]=0;55

56//

******主體**

57while(!z.empty())

5872}73

}74z.pop();

75 sum[x]++;

76/*

if(sum[x] > 2*m)//判斷負環 有時會用到

77*/

81 visit[x]=0;82

}83//**********

84for(int i=1;i<=n;i++) cout<"

";//

得到所有節點到源點的最短路

85return0;

86 }

最短路 SPFA演算法

spfa 是bellman ford的佇列優化,時效性相對好,時間複雜度o ke 與bellman ford演算法類似,spfa演算法採用一系列的鬆弛操作以得到從某乙個節點出發到達圖中其它所有節點的最短路徑。所不同的是,spfa演算法通過維護乙個佇列,使得乙個節點的當前最短路徑被更新之後沒有必要立刻...

最短路演算法 SPFA

單源最短路徑,不可以處理含負權邊的圖但可以用來判斷是否存在負權迴路 複雜度o ke k 2,e 為邊數 bellman ford 演算法的優化,實質與前演算法一樣,但優化的關鍵之處在於 只有那些前面被鬆弛過的點才有可能去鬆弛它們的鄰接點。include include include include...

最短路 spfa演算法

板子補完計畫絕讚繼續中 這篇部落格就來寫一寫spfa 這我居然板子都打錯了一次,我太弱啦!先來看一下定義 引自 首先說明,spfa是一種單源最短路徑演算法,所以以下所說的 某點的最短路徑長度 指的是 某點到源點的最短路徑長度 我們記源點為s,由源點到達點i的 當前最短路徑 為d i 開始時將所有d ...