我們可以把邊帶有權值的圖稱為帶權圖。邊的權值可以理解為兩點之間的距離。
一張圖任意兩點間會有不同的路徑相連。最短路徑就是指連線兩點的這些路徑中最短的一條。
我們有四種方法求出兩個點間最短的路徑
分別是floyed-warshall演算法(簡稱floyed演算法)
dijkstra演算法
bellman-ford演算法(簡稱ford演算法)
spfa演算法
注意,當出現負邊權時,有些方法並不適用。
今天,我們來講講spfa演算法。
****
spfa演算法是bellman-ford演算法的一種佇列實現(就是佇列優化的ford演算法),減少了不必要的計算。
spfa和廣搜bfs類似,但是不同的是,bfs**佇列的元素不可能進入佇列。而spfa中每個點可以重複進出佇列,被再次用來修改其他的點。
spfa演算法是一種效率很高的演算法,它時間複雜度為o(ke),k為常數,e為邊數。
我們定義乙個dis陣列,dis[i]表示從起點至i點的最短路徑,
flag[u]表示u點是否存在於佇列中。
初始化:
#define inf int_max
void start(int n)
開始spfa演算法
將起點u放入佇列,並標記u點存在於佇列中,並把頭指標向後移動一位
且dis[u]=0;
for迴圈查詢與u相連的所有點v,依次訪問每個點,並比較路徑長度
如果更小,則入隊,記錄路徑長度。
void solve(int p)}}
} } //我用的是鏈式前向星存圖,也可使用鄰接矩陣存圖。
由起點到終點n的最短路徑為dis[n],所以,易得**如下
void print(int p)
完整spfa**(包括鏈式前向星)如下
#define maxn 200001
#define inf int_max
int pre[maxn*2],now[maxn*2],son[maxn*2],len[maxn];
int n,m,p,e,tot=0,x,y;
int dis[maxn];
bool flag[maxn];
queueq;
inline void edge(int x,int y,int z)
struct spfa
void solve(int p)}}
} }
void print(int p)
}spfa;
洛谷p3371 單源最短路徑(弱化版)
入門oj 1652 最短路徑問題
關於最短路
把最近做的幾道最短路一起總結一下吧 poj1062 中文題,不解釋題意,對於渣渣來說,是先看別人題解後才做的,以酋長的允諾作為目標點,每乙個物品與替換物之間會有一條邊,由於交換有限制,所以建完圖後,以每乙個點為終點或是說最高點,先遍歷一次,把不能交換或間接交換的點去掉,然後再進行最短路尋找。實際就是...
關於最短路
模板 void dij p.push make pair d 1 1 while p.empty 為啥想到用最小堆?因為每次都是找與源點最近的,vis為0的點,想到了用優先佇列找的快一點細節 d陣列用pair形式表示,pair的first是距離,second是點的下標。pair跟結構體差不多,如果用...
最短路問題(1)
從圖中指定的一點出發走到某一目標點如果存在多種不同的走法,最短的是哪條路?其長度是多少?圖論中解決上述問題的方法都屬於最短路演算法。由於圖的特點不同 儲存結構不同 確立演算法的側重方向不同,所以演算法是多種多樣的。一 無權圖及樹網 在無權圖中,路徑長度只與路徑上的點數有關,而與路徑上的邊權和點權無關...