时间复杂度对比:
Dijkstra:O(n2)
Dijkstra + 优先队列(堆优化):O(2∗E+V∗logV)
SPFA:O(k∗E)O(k∗E) k为每个节点进入队列的次数,一般小于等于2,最坏情况为O(V∗E)
BellmanFord: O(V∗E)O(V∗E) O(V*E)O(V∗E),可检测负圈
Floyd: O(n3),计算每对节点之间的最短路径
结论:
①当权值为非负时,用Dijkstra。
②当权值有负值,且没有负圈,则用SPFA,SPFA能检测负圈,但是不能输出负圈。
③当权值有负值,而且可能存在负圈,则用BellmanFord,能够检测并输出负圈。
④SPFA检测负环:当存在一个点入队大于等于V次时,则有负环。
PS:优先队列和SPFA都有可能被题目卡数据……
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <utility>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
const int INF=0x3f3f3f3f;
const int Max=1e5+5;
typedef long long ll;
int dis[Max],head[Max],path[Max];
bool vis[Max];
struct edge
{
int u, v, w;
int next;
}e[2