摘自:https://blog.csdn.net/qq_36932169/article/details/78806863
Floyd算法是多源最短路算法,复杂度最高(n ^ 3),通常用在点比较少的起点不固定的问题中。能解决负边(负权)但不能解决负环。
Dijkstra算法是单源最短路算法,最常用时间复杂度(n ^ 2)优化后可以达到(nlogn),不能解决负边问题,稀疏图需要耗费比较多的空间。
SPFA算法适合稀疏图,可以解决带有负权边,负环的问题,但是在稠密图中效率比Dijkstra要低。
一. Floyd
#define MAX 65535
int Chara[N][N], p[N][N];//N为点的可能最多值
int n, m;//n个点,m条路
void Floyd()
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
p[i][j] = j;//初始化
}
}
for (int k = 0; k < n; k++)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (Chara[i][k] == MAX || Chara[k][j] == MAX) continue;
if (Chara[i][j] > Chara[i][k] + Chara[k][j])
{
//如果经过下标k顶点路径比原两点间路径更短,将当前两点权值设为更小的那一个
Chara[i][j] = Chara[i][k] + Chara[k][j];
p[i][j] = p[i][k];//路径设置经过下标k的顶点
}
}
}
}
}//a点到b点距离最短为Chara[a][b]
int main()
{
while (cin >> n >> m)
{
memset(Chara, 0x3f, sizeof(Chara));//初始化
for (int i = 0; i<m; i++)
{
int a, b, x;
scanf("%d %d %d", &a, &b, &x);//a到b的距离为x
if (x< Chara[a][b])
Chara[a][b] = Chara[b][a] = x;
}
for (int i = 0; i <= n; i++)
Chara[i][i] = 0;//到自身距离为0
Floyd();
if (Chara[s][t] == INF)//如果是无限大,输出-1表示无法到达
cout << -1 << endl;
else
cout << Chara[s][t] << endl;
}
return 0;
}
…
二. Dijkstra
#define INF 65535
int n, m,
s, t;//s为起点,t为终点
int Chara[N][N], dis[N], vis[N], p[i];//N为点的可能最多数
void Dijkstra(int src) //src传入的起点
{
for (int i = 0; i<m; i++) //初始化起点到所有点的距离
{
dis[i] = Chara[src][i];
vis[i] = 0;
p[i] = 0;
}
dis[src] = 0; //到自身距离为0
vis[src] = 1; //标记 注src=0
for (int i = 0; i<m; i++)
{
int ans = INF, k;
for (int j = 0; j<m; j++) // 寻找未被访问过距离起点v0最近的
{
if (!vis[j] && dis[j] < ans)
{
k = j;
ans = dis[j];
}
}
vis[k] = 1; //标记已访问
if (ans == INF) break; //表示剩下所有点都不通
for (int j = 0; j<m; j++) //松弛操作,更新起点到所有未访问点的距离
{
if (!vis[j] && dis[k] + Chara[k][j]<dis[j])
{
dis[j] = dis[k] + Chara[k][j];
p[j] = k;//存放前驱节点
}
}
}
}//s到t最短距离为dis[t]
//引用:Dijkstra(t),其他参照前面
//输出:printf("%d\n",dis[t]==INF?-1:dis[t]);
```
三.SPFA
const int INF = 0x3f
3f3f3f;
const int N = 210;
int n, m, s, t;
int dis[N], vis[N], sum[N];
struct node
{
int v; ///点
int weight; ///权值
};
vector<node>mp[N]; //储存边;
void SPFA(int src)//src为起点
{
int q;
queue<int>Q;
vis[src] = 1;
dis[src] = 0;
Q.push(src);
while (!Q.empty())
{
q = Q.front();
Q.pop();
vis[q] = 0;
for (int i = 0; i<mp[q].size(); i++)
{
if (dis[q] + mp[q][i].weight < dis[mp[q][i].v])
{
dis[mp[q][i].v] = dis[q] + mp[q][i].weight;
if (!vis[mp[q][i].v])
{
Q.push(mp[q][i].v);
vis[mp[q][i].v] = 1;
}
}
}
}
return;
}
int main()
{
while (cin >> n >> m)
{
memset(vis, 0, sizeof(vis));//初始化
memset(dis, INF, sizeof(dis));
int u, v, w;//u到v的权重为w
node ans;//答案
for (int i = 0; i < m; i++)//输入
{
cin >> u, v, w;
ans.v = v;
ans.weight = w;
mp[u].push_back(ans);
ans.v = u;
mp[v].push_back(ans);
}
cin >> s >> t;
SPFA(s);
printf("%d\n", dis[t] == INF ? -1 : dis[t]);//输出
for (int i = 0; i < n; i++)//初始化
mp[i].clear();
}
return 0;
}