时间复杂度对比:
Dijkstra:
Dijkstra + 优先队列(堆优化):
SPFA:
,
为每个节点进入队列的次数,一般小于等于
,最坏情况为
BellmanFord:
,可检测负圈
Floyd:
,计算每对节点之间的最短路径
结论:
当权值为非负时,用Dijkstra。
当权值有负值,且没有负圈,则用SPFA,SPFA能检测负圈,但是不能输出负圈。
当权值有负值,而且可能存在负圈,则用BellmanFord,能够检测并输出负圈。
SPFA检测负环:当存在一个点入队大于等于V次时,则有负环。
:优先队列和SPFA都有可能被题目卡数据
Floyd:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = INT_MAX/100;
int n, m, d[3000][3000];
void floyed() {
for(int k=0; k<n; k++) { //插入k点
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
if(d[i][k]<INF && d[k][j]<INF) //消除加法溢出问题
d[i][j]=min(d[i][j], d[i][k]+d[k][j]); //更新两点距离
}
}
}
}
void init() {
scanf("%d%d", &n, &m);
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++)
if(i==j) d[i][j]=0;
else d[i][j]=INF;
}
for(int i=0; i<m; i++) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
d[x-1][y-1]=z;
}
}
int main() {
init();
floyed();
}