bellman-ford算法
上节课我们学习了kruskal算法
今天我们来学习bellman-ford算法求最短路
求有负环最短路
原理:
在有负环的时候,理论上是没有最短路的
这个图是特例
非常暴力的方法
- for step = 1 → \to → n - 1
- 枚举每条边(a, b, c)
- 如果d[a]+c<d[b] d[b]=d[a]+c
就完了!
时间复杂度 O ( n 2 ) O(n^2) O(n2)
上一下代码
#include <iostream>
#include <cstdio>
using namespace std;
const int INF = (int) 1E9 + 7;
struct Edge
{
int a, b, c;
}
edge[100010];
int d[1000010];
int n, m;
void bellmanFord()
{
for(int i = 1; i <= n; i ++)
{
d[i] = INF;
}
d[1] = 0;
for(int step = 0; step < n - 1; step ++)
{
for(int i = 0; i < m; i ++)
{
int a = edge[i].a;
int b = edge[i].b;
int c = edge[i].c;
if(d[a] + c < d[b])
{
d[b] = d[a] + c;
}
}
}
if(d[n] == INF)
{
puts("can't arrive!");
return ;
}
bool flag = false;
for(int i = 0; i < m; i ++)
{
int a = edge[i].a;
int b = edge[i].b;
int c = edge[i].c;
if(d[a] + c < d[b])
{
d[b] = d[a] + c;
flag = true;
}
}
if(flag)
{
puts("circle");
}
else
{
printf("%d\n", d[n]);
}
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i ++)
{
scanf("%d%d%d", &edge[i].a, &edge[i].b, &edge[i].c);
}
bellmanFord();
return 0;
}