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++
- c++模板類C++
- SPFA演算法演算法
- C++模板沉思錄C++
- c++函式模板C++函式
- C++ 模板與STLC++
- c++ 模板模板引數("Template Template Parameters")C++
- C++模板沉思錄(上)C++
- C++開發:template,模板C++
- C++模板類複習C++
- C++泛型一:模板C++泛型
- c/c++ 模板 型別推斷C++型別
- C/C++呼叫快排的模板C++
- C++模板超程式設計(C++ template metaprogramming)C++程式設計
- 模板方法模式(c++實現)模式C++
- C++程式設計模板2C++程式設計
- C++模板超程式設計C++程式設計
- c++ 模板之 抽象工廠C++抽象
- C++標準模板庫------容器C++
- C++中的模板(templates) (轉)C++
- c++可變模板引數C++
- C++模板的定製二:定製C++類 (轉)C++
- 最短路-SPFA演算法&Floyd演算法演算法
- C++模板的定製三:部分定製C++類 (轉)C++
- C++ 函式過載和模板C++函式
- C++反射機制:可變引數模板實現C++反射C++反射
- C++模板的定製一:定製函式模板 (轉)C++函式
- C++演算法——BFSC++演算法
- C++容器演算法C++演算法
- C++智慧指標模板類複習C++指標
- C++知識點隨筆(六):模板C++
- 深入實踐c++模板程式設計C++程式設計
- C++基礎::變數模板(variable template)C++變數
- C++模板超程式設計[metaprogram] (轉)C++程式設計
- C++反射機制:可變引數模板實現C++反射薦C++反射
- C++反射機制:可變引數模板實現C++反射(二)C++反射
- 現代c++與模板超程式設計C++程式設計