• bellman_ford


    bellman_ford算法:有边数限制的最短路,可以处理重边、负边和自环。

    给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数。

    请你求出从1号点到n号点的最多经过k条边的最短距离,如果无法从1号点走到n号点,输出impossible。

    注意:图中可能 存在负权回路

    输入格式

    第一行包含三个整数n,m,k。

    接下来m行,每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。

    输出格式

    输出一个整数,表示从1号点到n号点的最多经过k条边的最短距离。

    如果不存在满足条件的路径,则输出“impossible”。

    数据范围

    1≤n,k≤500,

    1≤m≤10000,

    任意边长的绝对值不超过10000。

    输入样例:

    3 3 1

    1 2 1

    2 3 1

    1 3 3

    输出样例:

    3

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N = 510, M = 10001;
    int d[N], backup[N];
    int n, m, k;
    struct edges{
        int a, b, w;
    }Edge[M];
    
    int bellman_ford()
    {
        memset(d, 0x3f, sizeof d);
        d[1] = 0;
        for(int i = 0;i<k;i++)
        {
            memcpy(backup, d, sizeof d);
            for(int j = 0;j < m;j++)//注意这里是要循环结束到m,因为输入的边数就是m。
            {
                int a = Edge[j].a, b = Edge[j].b, w = Edge[j].w;
                d[b] = min(d[b], backup[a] + w);
            }
        }
        if(d[n] > 0x3f3f3f3f / 2) return -1;
        return d[n];
    }
    
    int main()
    {
        cin>>n>>m>>k;
        for(int i = 0;i<m;i++)
        {
            int a, b, w;
            cin>>a>>b>>w;
            Edge[i] = {a,b,w};
        }
        int t = bellman_ford();
        if(t == -1) cout<<"impossible"<<endl;
        else cout<<t<<endl;
    }

    限制多少边就循环多少次,放进备份数组里面是为了防止本次循环就发生串联,等到k下一次循环的时候再用重新复制过的备份数组,这样就可以在之前的基础上继续前进 而不会 超出k条边的限制了。

    第一次只会更新从起点出发一条边能到达的地方,下一次就更新第二条能到达的,以此递增类推。

    k = 1, d[1] = 0, d[2] = 1, d[3] = 3, 这里d[3]不会更新为d[2] + 1,因为用的是上次备份的d[2] +oo

    k = 2, d[1] = 0, d[2] = 1, d[3] = min(3, 1 + 1) = 2;

    for n 次

      for所有边a, b, w

        dist[b] = min(dist[b], dist[a] + w); //每次无脑的对所有的边进行松弛操作。

  • 相关阅读:
    外观模式
    建造者模式
    原型模式
    工厂模式
    单例模式
    设计模式入门
    SpringBoot-SpringMVC开发总结
    SpringBoot日志
    IDEA Basics
    Kafka基础学习
  • 原文地址:https://www.cnblogs.com/longxue1991/p/12709654.html
Copyright © 2020-2023  润新知