一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第19天,点击查看活动详情。
Bellman-Ford
算法思想
这个算法存边直接开一个结构体即可,不用什么邻接表之类的
- for循环n次
- for循环所有边
a, b, w:表示存在一条从a走到b的边,权重是w - 更新一下最短距离:
dist[b] = min(dist[b], dist[a] + w)
注意:
- 求最短路的时候,如果有负权回路的话,最短路不一定存在
时间复杂度:
O(m * n)
题目
www.acwing.com/problem/con…
有负权边:不能用Dijkstra算法
有边数限制:存在负权回路也无所谓的
代码
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 510, M = 10010;
int n, m, k;
int dist[N], backup[N]; // dist:存的距离 backup:
struct Edge // 存所有边,a:起点; b:终点; c = 权重
{
int a, b, w;
}edges[M];
int bellman_ford()
{
// 初始化
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
for (int i = 0; i < k; i++)
{
// 每次进行一次新的迭代之前,给dist数组备份一下
memcpy(backup, dist, sizeof dist);
// 遍历所有边
for (int j = 0; j < m; j++)
{
int a = edges[j].a, b = edges[j].b, w = edges[j].w;
dist[b] = min(dist[b], backup[a] + w); // 只用上一次更新迭代结果来更新这次的距离
}
}
return dist[n];
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
// 读入m条边
for (int i = 0; i < m; i++)
{
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
edges[i] = {a, b, w};
}
int t = bellman_ford();
if (t > 0x3f3f3f3f / 2) puts("impossible"); // 最短路不存在
else printf("%d\n", t);
return 0;
}
Floyd
算法思想
这个算法存边直接开一个结构体即可,不用什么邻接表之类的
- for循环n次
- for循环所有边
a, b, w:表示存在一条从a走到b的边,权重是w - 更新一下最短距离:
dist[b] = min(dist[b], dist[a] + w)
注意:
- 求最短路的时候,如果有负权回路的话,最短路不一定存在
时间复杂度:
O(m * n)
题目
www.acwing.com/problem/con…
有负权边:不能用Dijkstra算法
有边数限制:存在负权回路也无所谓的
代码
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 510, M = 10010;
int n, m, k;
int dist[N], backup[N]; // dist:存的距离 backup:
struct Edge // 存所有边,a:起点; b:终点; c = 权重
{
int a, b, w;
}edges[M];
int bellman_ford()
{
// 初始化
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
for (int i = 0; i < k; i++)
{
// 每次进行一次新的迭代之前,给dist数组备份一下
memcpy(backup, dist, sizeof dist);
// 遍历所有边
for (int j = 0; j < m; j++)
{
int a = edges[j].a, b = edges[j].b, w = edges[j].w;
dist[b] = min(dist[b], backup[a] + w); // 只用上一次更新迭代结果来更新这次的距离
}
}
return dist[n];
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
// 读入m条边
for (int i = 0; i < m; i++)
{
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
edges[i] = {a, b, w};
}
int t = bellman_ford();
if (t > 0x3f3f3f3f / 2) puts("impossible"); // 最短路不存在
else printf("%d\n", t);
return 0;
}