注意:用该算法求最短路,在有边数限制的情况下可以存在负权回路!且对所走的边的数量有要求时只能用该算法实现!
解析:因为如果没有边数限制,存在负权回路的时候可能会造成求出来的是负无穷(也就是不存在),而有变数限制的时候只循环规定的次数就会跳出循环。
思路:每次用上一次更新的点来更新该次的点!a -> b的长度为c (dist[b] = min(dist[b] , last[a] + c) )。
强烈建议自己按照这个代码画图走一遍才能理解的更加深刻!
代码:
#include
#include
using namespace std;
const int N = 1e4 + 10;
int dist[N];//存放有边数限制的最短距离
int last[N];//存放上一次更新的所有点的距离
int n,m,k;//n个点,m条边,限制k条边。
struct Edge
{
int a,b,c;
}edges[N];
void bellman_ford()
{
dist[1] = 0;//更新第一个点到第一个点的最短距离为0
for(int i = 0 ; i < k;i ++)
{
memcpy(last,dist,sizeof dist);//因为这里有边数限制,所以每次更新都要备份一份更新后的点。
for(int i = 0 ; i < m ; i ++)
{
struct Edge e = edges[i];
dist[e.b] = min(dist[e.b] , last[e.a] + e.c);//用上一次更新的点来更新数据!
}
}
}
int main()
{
cin>>n>>m>>k;
memset(dist,0x3f,sizeof dist);
for(int i=0;i>a>>b>>c;
edges[i] = {a,b,c};
}
bellman_ford();
if(dist[n] > 0x3f3f3f3f / 2) cout<<"impossible";
else cout<
步骤总结: