spfa演算法——最短路徑
粗略講講spfa演算法的原理,spfa演算法是2023年西南交通大學段凡丁提出
是一種求單源最短路的演算法
演算法中需要用到的主要變數
int n; //表示n個點,從1到n標號
int s,t; //s為源點,t為終點
int d[n]; //d[i]表示源點s到點i的最短路
int p[n]; //記錄路徑(或者說記錄前驅)
queue q; //乙個佇列,用stl實現,當然可有手打佇列,無所謂
bool vis[n]; //vis[i]=1表示點i在佇列中 vis[i]=0表示不在佇列中
幾乎所有的最短路演算法其步驟都可以分為兩步
1.初始化
2.鬆弛操作
初始化: d陣列全部賦值為inf(無窮大);p陣列全部賦值為s(即源點),或者賦值為-1,表示還沒有知道前驅
然後d[s]=0; 表示源點不用求最短路徑,或者說最短路就是0。將源點入隊;
(另外記住在整個演算法中有頂點入隊了要記得標記vis陣列,有頂點出隊了記得消除那個標記)
佇列+鬆弛操作
讀取隊頭頂點u,並將隊頭頂點u出隊(記得消除標記);將與點u相連的所有點v進行鬆弛操作,如果能更新估計值(即令d[v]變小),那麼就更新,另外,如果點v沒有在佇列中,那麼要將點v入隊(記得標記),如果已經在佇列中了,那麼就不用入隊
以此迴圈,直到隊空為止就完成了單源最短路的求解
spfa可以處理負權邊
定理: 只要最短路徑存在,上述spfa演算法必定能求出最小值。
證明:每次將點放入隊尾,都是經過鬆弛操作達到的。換言之,每次的優化將會有某個點v的最短路徑估計值d[v]變小。所以演算法的執行會使d越來越小。由於我們假定圖中不存在負權迴路,所以每個結點都有最短路徑值。因此,演算法不會無限執行下去,隨著d值的逐漸變小,直到到達最短路徑值時,演算法結束,這時的最短路徑估計值就是對應結點的最短路徑值。(證畢)
期望的時間複雜度o(ke), 其中k為所有頂點進隊的平均次數,可以證明k一般小於等於2。
判斷有無負環:
如果某個點進入佇列的次數超過n次則存在負環(spfa無法處理帶負環的圖)
spfa的兩種寫法,bfs和dfs,bfs判別負環不穩定,相當於限深度搜尋,但是設定得好的話還是沒問題的,dfs的話判斷負環很快
int spfa_bfs(int s)}}
}return ok;
}
int spfa_dfs(int u)
else
return 1;}}
vis[u]=0;
return 0;
}
有同感的話
在對的時間,遇見對的人,是一種幸福。在對的時間,遇見錯的人,是一場悲傷。在錯的時間,遇見對的人,是一聲嘆息。在錯的時間,遇見錯的人,是乙份無奈。每個故事就是乙個緣,不經意的錯過就變成了偶然,只有經得起時間的考驗,那才是一生一世不變的真緣。世間有很多事情,是受傷受挫折也無法改變的,要麼什麼都不做,要麼...
最短路徑(二)Bellman Ford(負權)
給定乙個n個點m條邊的有向圖,圖中可能存在重邊和自環,邊權可能為負數。請你求出從1號點到n號點的最多經過k條邊的最短距離,如果無法從1號點走到n號點,輸出impossible。注意 圖中可能 存在負權迴路 輸入格式 第一行包含三個整數n,m,k。接下來m行,每行包含三個整數x,y,z,表示存在一條從...
《三體》中超級悲壯的話有哪些?
1 我看到整個太陽系變成一幅畫,一幅二維的話,我們的家園成為了一幅畫。你如果看過三體,當整個太陽系都變成一幅畫的時候,又悲壯又沉痛。太陽系2 失去人性失去很多,失去獸性失去一切。點評 這是韋德說的一句話,人們由於不平等以及各種爭論,所以放棄了製造曲率飛船 除了韋德偷偷製造的那一艘之外 逃離太陽系。最...