單源最短路 SPFA 演算法模板
阿新 • • 發佈:2019-01-10
簡介
在圖論中,最短路是十分重要的一部分,在很多問題中都有涉及
而現在所講的 SPFA 演算法是十分優秀的演算法,時間複雜度為
O(k∗E) 其中
E 是圖的邊數,而k 是一個常數,一般極小。事實上 SPFA 就是在 Bellman-ford 演算法的基礎上加上一個佇列優化,減少了冗餘的鬆弛操作,是一種高效的最短路演算法。
而且 SPFA 還能判負環,這種情況下類似 Dijkstra 演算法等便沒有了用武之地!
用法
在佇列中進行,在點出隊入隊中更新值
SPFA演算法(BFS)模板如下:
void spfa_bfs(int st)
{
memset(dis,60,sizeof(dis));
memset(bz,false ,sizeof(bz));
int l=0,r=1;
dis[que[1]=st]=0;
while(l<r)
{
int now=que[++l];
bz[now]=false;
for(int i=first[now];i;i=next[i])
if(dis[now]+w[i]<dis[en[i]])
{
dis[en[i]]=dis[now]+w[i];
if(!bz[en[i]]) bz[que[++r]=en[i]]=true ;
}
}
return false;
}
註釋:其中
que[] 為佇列,dis[] 為點到源點距離,l,r 分別左右指標,bz[] 為標誌->點是否入隊。SPFA演算法(DFS)模板如下:
void spfa_dfs(int x)
{
bz[x]=true;
for(int i=first[x];i;i=next[i])
if(dis[now]+w[i]<dis[en[i]])
{
dis[en[i]]=dis[now]+w[i];
if (!bz[en[i]]]) spfa(en[i]);
}
bz[x]=false;
}
判負環
SPFA演算法還有一個大優點是可以判負環
利用 SPFA 演算法判斷負環有兩種方法:
- SPFA演算法 的 dfs 形式,判斷條件是 存在一點在一條路徑上出現多次。
- SPFA演算法 的 bfs 形式,判斷條件是 存在一點入隊次數大於總頂點數。
總結
- SPFA演算法效率高,實用性強,是很有用的演算法!