bellman - ford算法c++

(最短路III)bellman - ford算法(适用于含负权边的图)

注意:用该算法求最短路,在有边数限制的情况下可以存在负权回路!且对所走的边的数量有要求时只能用该算法实现!

解析:因为如果没有边数限制,存在负权回路的时候可能会造成求出来的是负无穷(也就是不存在),而有变数限制的时候只循环规定的次数就会跳出循环。

思路:每次用上一次更新的点来更新该次的点!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<

步骤总结:

  1. 更新第一个点为0;
  2. 遍历k次(限制k条边);
  3. 每次备份更新的数据;
  4. dist[e.b] = min(dist[e.b] , last[e.a] + e.c);(用上一次更新的数据来更新)

你可能感兴趣的:(算法,算法,c++,图论)