摘要:
Floyd算法模板
问题描述:
原题详见洛谷P1629邮递员送信
算法分析:
相比于经典的迪杰斯特拉算法和spfa算法,Floyd算法更适合求解多源点最短路径,即n个点之间的最短路径分别是多少。FLoyd算法和运行n次dijskral算法的时间复杂度都是 O ( n 3 ) O(n^3) O(n3) ,但是Floyd算法可以处理含有负权边的图,且实验证明Floyd算法更快
代码以及详细注释:
//洛谷P1629题解,
#include <iostream>
#include <vector>
using namespace std;
#pragma warning(disable:4996)
#define INF 10000000
class Solution {
public:
int n; //点数
int m;//边数
vector<vector<int>> cost; //代价矩阵
vector<vector<int>> key; //保存点i到点j最短路径所经过的点的编号
void Floyd() {
cin >> n >> m;
cost.resize(n + 1, vector<int>(n + 1, INF));
//key.resize(n + 1, vector<int>(n + 1, 0));
for(int i=1;i<=m;++i)
{
int x, y, w;
cin >> x >> y >> w;
cost[x][y] = min(cost[x][y], w);
}
for (int i = 1; i <= n; ++i)
cost[i][i] = 0;
for(int k=1;k<=n;++k)
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if (cost[i][k] != INF && cost[k][j] != INF && cost[i][j] > cost[i][k] + cost[k][j])
{
cost[i][j] = cost[i][k] + cost[k][j];
key[i][j] = k; //对此题没啥用,但是可以求出每一条最短路径经过的点的信息
}
int ans = 0;
for (int i = 2; i <= n; ++i)
ans += (cost[1][i] + cost[i][1]);
cout << ans;
}
//附加一个用于实现路径输出的函数
void outpath(int origin, int destination) {
if (cost[origin][destination] == INF) {
cout << "there is no path from " << origin << "to " << destination << endl;
}
cout << origin;
out(origin, destination);
}
void out(int origin,int destination) {
if (origin == destination)
return;
if (key[origin][destination] == 0)
cout <<"->"<<destination;
else {
out(origin, key[origin][destination]);
out(key[origin][destination], destination);
}
}
};
int main()
{
//freopen("in.txt", "r", stdin);
Solution s;
s.Floyd();
/*cout << endl;
s.outpath(1, 4);*/
return 0;
}