SPFA演算法模板(C/C++)
單源最短路徑演算法,可以用於解決帶負邊權的情況。是佇列優化的Bellman-Ford演算法,時間複雜度O(nm)。
樸素spfa演算法模板
#include <stdio.h>
#include <string.h>
const int N = 1010, M = 2e6, INF = 1e9;
int n, m; //n是節點數,m是邊數
int dist[N], q[N]; //dist[i]表示源點到i點的最短距離
int h[N], to[M], w[M], ne[M], idx; //idx初始化為0
bool st[N]; //儲存每個點是否在佇列中
//新增邊表示a到b有一條單向邊,權值為c
void add(int a, int b, int c){
to[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
//求源點s到其它點的最短路徑
void spfa(int s){
int hh, tt; //佇列頭指標和尾指標
memset(st, false, sizeof(st));
for(int i = 1; i <= n; i++) dist[i] = INF;
dist[s] = 0;
q[tt++] = s;
st[s] = true;
while(hh != tt){ //佇列不為空
int t = q[hh++];
st[t] = false;
if(hh == N) hh = 0;
for(int i = h[i]; ~i; i = ne[i]){
if(dist[t] + w[i] < dist[to[i]]){
dist[to[i]] = dist[t] + w[i];
if(!st[to[i]]){
st[to[i]] = true;
q[tt++] = to[i];
if(tt == N) tt = 0;
}
}
}
}
}
int main(void){
int a, b, c;
scanf("%d %d %d", &n, &m, &s);
memset(h, -1, sizeof(h));
for(int i = 1; i <= m; i++){
scanf("%d %d %d", &a, &b, &c);
add(a, b, c);
}
spfa(s);
for(int i = 1; i <= n; i++){
if(dist[i] == INF) puts("NO PATH");
else printf("%d\n", dist[i]);
}
return 0;
}
SLF優化的SPFA演算法
SLF 優化:將普通佇列換成雙端佇列,每次將入隊結點距離和隊首比較,如果更大則插入至隊尾,否則插入隊首
#include <stdio.h>
#include <string.h>
#include <deque>
using namespace std;
const int N = 1010, M = 2e6, INF = 1e9;
int dist[N];
int h[N], to[M], w[M], ne[M], idx;
bool st[N];
int n, m;
void add(int a, int b, int c){
to[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
void spfa(int s){
memset(st, false, sizeof(st));
for(int i = 1; i <= n; i++) dist[i] = INF;
dist[s] = 0;
deque<int> q;
q.push_front(s);
st[s] = true;
while(!q.empty()){
int t = q.front();
q.pop_front();
st[t] = false;
for(int i = h[t]; ~i; i = ne[i]){
if(dist[t] + w[i] < dist[to[i]]){
dist[to[i]] = dist[t] + w[i];
if(!st[to[i]]){
if(!q.empty() && dist[to[i]] < dist[q.front()]){
q.push_front(to[i]);
}
else q.push_back(to[i]);
st[to[i]] = true;
}
}
}
}
}
相關文章
- C++ 模板C++
- C++——模板C++
- SPFA演算法演算法
- c++函式模板C++函式
- C++模板沉思錄C++
- c++ 模板模板引數("Template Template Parameters")C++
- C++函式模板案例C++函式
- C++泛型一:模板C++泛型
- C++模板沉思錄(上)C++
- C++開發:template,模板C++
- c/c++ 模板 型別推斷C++型別
- c++可變模板引數C++
- 模板方法模式(c++實現)模式C++
- C++提高程式設計-模板C++程式設計
- C++ 函式過載和模板C++函式
- C++反射機制:可變引數模板實現C++反射C++反射
- 最短路-SPFA演算法&Floyd演算法演算法
- C++容器演算法C++演算法
- C++演算法——BFSC++演算法
- C++反射機制:可變引數模板實現C++反射(二)C++反射
- C++反射機制:可變引數模板實現C++反射薦C++反射
- C++關於DLL匯出模板類和模板函式C++函式
- c++ 遞推演算法C++演算法
- C++基於模板實現智慧指標C++指標
- 關於C++當中的“模板函式”C++函式
- c++函式模板和執行機制C++函式
- 現代c++與模板超程式設計C++程式設計
- c++函式模板和類别範本C++函式
- VS Code C++ 專案快速配置模板C++
- C/C++ 常用加密與解密演算法C++加密解密演算法
- (C++模板程式設計):策略(policy)技術中的演算法策略與總結C++程式設計演算法
- C++演算法 線段樹C++演算法
- 模式匹配kmp演算法(c++)模式KMP演算法C++
- C++實現Prim演算法C++演算法
- C++ 可變引數模板遞迴展開C++遞迴
- [C++ Daily] 使用模板實現簡易Python WrapperC++AIPythonAPP
- C++模板函式實現型別推導C++函式型別
- Win32 C++程式碼快速驗證模板Win32C++