题目思路
本题与Dijkstra算法的最大区别:1、存在负权回路。2、最多经过k条边。
- Dijkstra算法无法解决存在负权的最短距离问题,具体原因可以看此篇文章,给出了详细步骤。www.acwing.com/solution/co…
backup
数组的作用。为了避免节点最短距离的串连,在有k条边数限制的情况下,我们需要使用上次循环的dist
数据,而不能使用本次循环中的dist
。- 外层循环k次,表示最多只能经过k条边。内层循环m次,将所有的边进行松弛操作。
- 最后一步,
dist[n] > 0x3f3f3f3f / 2
,可能存在dist[n]
已经减去一部分的情况。
C++ 代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 510, M = 10010;
int n, m, k;
int dist[N];
int backup[N];
struct Edge
{
int a, b, w;
}edge[M];
void bellman_ford()
{
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
for (int i = 0; i < k; i++)
{
memcpy(backup, dist, sizeof dist);
for (int j = 0; j < m; j++)
{
auto e = edge[j];
dist[e.b] = min(dist[e.b], backup[e.a] + e.w);
}
}
if (dist[n] > 0x3f3f3f3f / 2)
{
cout << "impossible";
}
else
{
cout << dist[n];
}
}
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
cin >> n >> m >> k;
for (int i = 0; i < m; i++)
{
int a, b, w;
cin >> a >> b >> w;
edge[i] = { a,b,w };
}
bellman_ford();
return 0;
}