最短路模板——Floyd

时间复杂度对比:
Dijkstra: O ( n 2 ) O(n^2)
Dijkstra + 优先队列(堆优化): O ( 2 E + V l o g V ) O(2*E+V*logV)
SPFA: O ( k E ) O(k*E) k k 为每个节点进入队列的次数,一般小于等于 2 2 ,最坏情况为 O ( V E ) O(V*E)
BellmanFord: O ( V E ) O(V*E) ,可检测负圈
Floyd: O ( n 3 ) O(n^3) ,计算每对节点之间的最短路径

结论:

当权值为非负时,用Dijkstra。
当权值有负值,且没有负圈,则用SPFA,SPFA能检测负圈,但是不能输出负圈。
当权值有负值,而且可能存在负圈,则用BellmanFord,能够检测并输出负圈。
SPFA检测负环:当存在一个点入队大于等于V次时,则有负环。

P S PS :优先队列和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();
}

猜你喜欢

转载自blog.csdn.net/Scar_Halo/article/details/83314976