Bellman-ford算法 注释版
作者:
马老师糖尿病害我蛀牙
,
2024-03-28 09:16:57
,
所有人可见
,
阅读 15
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 510, M = 10010; // 定义最大顶点数N和最大边数M
struct Edge
{
int a, b, c; // 定义边的结构体,a和b是这条边的两个顶点,c是边的权重
}edges[M]; // 存储所有边的数组
int n, m, k; // n是顶点数,m是边数,k是Bellman-Ford算法执行的轮数
int dist[N]; // 存储源点到其他顶点的最短距离
int last[N]; // 用来在每次迭代中储存上一轮顶点的最短距离
void bellman_ford()
{
memset(dist, 0x3f, sizeof dist); // 使用0x3f来初始化dist数组,这是一个很大的数,代表无穷大
dist[1] = 0; // 将起点到自己的距离设置为0
for (int i = 0; i < k; i ++ ) // 循环k次,每次尝试更新所有的边
{
memcpy(last, dist, sizeof dist); // 复制dist到last,这样我们就不会用新的未经验证的距离来更新其他的距离
for (int j = 0; j < m; j ++ ) // 遍历所有边
{
auto e = edges[j]; // 获取当前边
dist[e.b] = min(dist[e.b], last[e.a] + e.c); // 松弛操作:如果通过这条边可以得到一个更短的路径,则更新dist数组中的值
}
}
}
int main()
{
scanf("%d%d%d", &n, &m, &k); // 输入顶点数,边数和迭代次数
for (int i = 0; i < m; i ++ ) // 读入所有的边信息
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c); // 输入每条边的起点,终点和权重
edges[i] = {a, b, c}; // 存储边信息
}
bellman_ford(); // 执行Bellman-Ford算法
// 如果最终dist数组中的目标顶点值大于0x3f3f3f3f的一半,由于0x3f3f3f3f代表无穷,该值的一半用来避免整数溢出
// 代表没有路径到达顶点n,输出"impossible"
if (dist[n] > 0x3f3f3f3f / 2) puts("impossible");
else printf("%d\n", dist[n]); // 否则,输出到达顶点n的最短距离
return 0; // 程序结束
}