首页 > 编程语言 >图论day64 :最短路径算法 | SPFA(Bellman_ford的队列优化版)、城市间货物运输 I、Ⅱ、Ⅲ、Bellman_ford算法思维导图汇总

图论day64 :最短路径算法 | SPFA(Bellman_ford的队列优化版)、城市间货物运输 I、Ⅱ、Ⅲ、Bellman_ford算法思维导图汇总

时间:2024-10-17 19:51:35浏览次数:9  
标签:运输成本 int 城市 Bellman ford 算法 minDist 回路 负权

图论day64 :最短路径算法 | SPFA(Bellman_ford的队列优化版)、94.城市间货物运输 I(卡码网)【SPFA算法 + 邻接表优化】、95.城市间货物运输 II(判断负权回路)、96.城市间货物运输 III【已知有负权回路,该如何计算】、Bellman_ford算法思维导图汇总

SPFA(Bellman_ford的队列优化版)

在这里插入图片描述

94.城市间货物运输 I(卡码网)【SPFA算法 + 邻接表优化】

题目描述

某国为促进城市间经济交流,决定对货物运输提供补贴。共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。

网络中的道路都有各自的运输成本和政府补贴,道路的权值计算方式为:运输成本 - 政府补贴。权值为正表示扣除了政府补贴后运输货物仍需支付的费用;权值为负则表示政府的补贴超过了支出的运输成本,实际表现为运输过程中还能赚取一定的收益。

请找出从城市 1 到城市 n 的所有可能路径中,综合政府补贴后的最低运输成本。如果最低运输成本是一个负数,它表示在遵循最优路径的情况下,运输过程中反而能够实现盈利。

城市 1 到城市 n 之间可能会出现没有路径的情况,同时保证道路网络中不存在任何负权回路。

输入描述

第一行包含两个正整数,第一个正整数 n 表示该国一共有 n 个城市,第二个整数 m 表示这些城市中共有 m 条道路。

接下来为 m 行,每行包括三个整数,s、t 和 v,表示 s 号城市运输货物到达 t 号城市,道路权值为 v (单向图)。

输出描述

如果能够从城市 1 到连通到城市 n, 请输出一个整数,表示运输成本。如果该整数是负数,则表示实现了盈利。如果从城市 1 没有路径可达城市 n,请输出 “unconnected”。

输入示例

6 7
5 6 -2
1 2 1
5 3 1
2 5 2
2 4 -3
4 6 4
1 3 5

输出示例

1

提示信息

img

示例中最佳路径是从 1 -> 2 -> 5 -> 6,路上的权值分别为 1 2 -2,最终的最低运输成本为 1 + 2 + (-2) = 1。

示例 2:

4 2
1 2 -1
3 4 -1

在此示例中,无法找到一条路径从 1 通往 4,所以此时应该输出 “unconnected”。

数据范围:

1 <= n <= 1000;
1 <= m <= 10000;

-100 <= v <= 100;

#include <iostream>
#include <vector>
#include <queue>
#include <list>
#include <climits>
using namespace std;

struct Edge
{
    int to;
    int val;
    Edge(int t,int v):to(t),val(v){}
};

int main()
{
    int n,m,p1,p2,val;
    cin>>n>>m;

    vector<list<Edge>> grid(n+1);

    vector<bool> isInQueue(n+1,false);

    for(int i=0;i<m;i++)
    {
        cin>>p1>>p2>>val;
        grid[p1].push_back(Edge(p2,val));
    }
    int start=1;
    int end=n;

    vector<int> minDist(n+1,INT_MAX);
    minDist[start]=0;

    queue<int> que;
    que.push(start);
    isInQueue[start]=true;

    while(!que.empty())
    {
        int node=que.front();
        que.pop();
        isInQueue[node]=false;
        for(Edge edge:grid[node])
        {
            int from=node;
            int to=edge.to;
            int value=edge.val;
            if(minDist[to]>minDist[from]+value)//这里不用限制minDist[from]!=INT_MAX
            {
                minDist[to]=minDist[from]+value;
                if(isInQueue[to]==false)
                {
                    que.push(to);
                    isInQueue[to]=true;
                }
            }
        }
    }
    if (minDist[end] == INT_MAX) cout << "unconnected" << endl; // 不能到达终点
    else cout << minDist[end] << endl;
}

95.城市间货物运输 II【判断负权回路】

题目描述

某国为促进城市间经济交流,决定对货物运输提供补贴。共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。

网络中的道路都有各自的运输成本和政府补贴,道路的权值计算方式为:运输成本 - 政府补贴。权值为正表示扣除了政府补贴后运输货物仍需支付的费用;权值为负则表示政府的补贴超过了支出的运输成本,实际表现为运输过程中还能赚取一定的收益。

然而,在评估从城市 1 到城市 n 的所有可能路径中综合政府补贴后的最低运输成本时,存在一种情况:**图中可能出现负权回路。**负权回路是指一系列道路的总权值为负,这样的回路使得通过反复经过回路中的道路,理论上可以无限地减少总成本或无限地增加总收益。为了避免货物运输商采用负权回路这种情况无限的赚取政府补贴,算法还需检测这种特殊情况。

请找出从城市 1 到城市 n 的所有可能路径中,综合政府补贴后的最低运输成本。同时能够检测并适当处理负权回路的存在。

城市 1 到城市 n 之间可能会出现没有路径的情况

输入描述

第一行包含两个正整数,第一个正整数 n 表示该国一共有 n 个城市,第二个整数 m 表示这些城市中共有 m 条道路。

接下来为 m 行,每行包括三个整数,s、t 和 v,表示 s 号城市运输货物到达 t 号城市,道路权值为 v。

输出描述

如果没有发现负权回路,则输出一个整数,表示从城市 1 到城市 n 的最低运输成本(包括政府补贴)。如果该整数是负数,则表示实现了盈利。如果发现了负权回路的存在,则输出 “circle”。如果从城市 1 无法到达城市 n,则输出 “unconnected”。

输入示例

4 4
1 2 -1
2 3 1
3 1 -1 
3 4 1

输出示例

circle

提示信息

路径中存在负权回路,从 1 -> 2 -> 3 -> 1,总权值为 -1,理论上货物运输商可以在该回路无限循环赚取政府补贴,所以输出 “circle” 表示已经检测出了该种情况。

数据范围:

1 <= n <= 1000;
1 <= m <= 10000;

-100 <= v <= 100;

#include <iostream>
#include <vector>
#include <list>
#include <climits>
using namespace std;

int main()
{
    int n,m,p1,p2,val;
    cin>>n>>m;

    vector<vector<int>> grid;

    for(int i=0;i<m;i++)
    {
        cin>>p1>>p2>>val;
        grid.push_back({p1,p2,val});
    }
    int start=1;
    int end=n;

    vector<int> minDist(n+1,INT_MAX);
    minDist[start]=0;
    bool flag=false;
    for(int i=1;i<=n;i++)
    {
        for(vector<int> &side:grid)
        {
            int from=side[0];
            int to=side[1];
            int price=side[2];
            if(i<n)
            {
                if(minDist[from]!=INT_MAX&&minDist[to]>minDist[from]+price)
                    minDist[to]=minDist[from]+price;
            }
            else
            {
                if(minDist[from]!=INT_MAX&&minDist[to]>minDist[from]+price)
                    flag=true;
            }
        }
    }
    if(flag) cout<<"circle"<<endl;
    else if (minDist[end] == INT_MAX)
    {
        cout << "unconnected" << endl;
    }
    else
    {
        cout << minDist[end] << endl;
    }
}

在这里插入图片描述

96.城市间货物运输 III【已知有负权回路,该如何计算】

题目描述

某国为促进城市间经济交流,决定对货物运输提供补贴。共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。

网络中的道路都有各自的运输成本和政府补贴,**道路的权值计算方式为:运输成本 - 政府补贴。**权值为正表示扣除了政府补贴后运输货物仍需支付的费用;权值为负则表示政府的补贴超过了支出的运输成本,实际表现为运输过程中还能赚取一定的收益。

请计算在最多经过 k 个城市的条件下,从城市 src 到城市 dst 的最低运输成本。

输入描述

第一行包含两个正整数,第一个正整数 n 表示该国一共有 n 个城市,第二个整数 m 表示这些城市中共有 m 条道路。

接下来为 m 行,每行包括三个整数,s、t 和 v,表示 s 号城市运输货物到达 t 号城市,道路权值为 v。

最后一行包含三个正整数,src、dst、和 k,src 和 dst 为城市编号,从 src 到 dst 经过的城市数量限制。

输出描述

输出一个整数,表示从城市 src 到城市 dst 的最低运输成本,如果无法在给定经过城市数量限制下找到从 src 到 dst 的路径,则输出 “unreachable”,表示不存在符合条件的运输方案。

输入示例

6 7
1 2 1
2 4 -3
2 5 2
1 3 5
3 5 1
4 6 4
5 6 -2
2 6 1

输出示例

0

提示信息

从 2 -> 5 -> 6 中转一站,运输成本为 0。

1 <= n <= 1000;

1 <= m <= 10000;

-100 <= v <= 100;

#include <iostream>
#include <vector>
#include <list>
#include <climits>
using namespace std;

int main()
{
    int n,m,p1,p2,val,k,src,dst;
    cin>>n>>m;
    vector<vector<int>> grid;
    for(int i=0;i<m;i++)
    {
        cin>>p1>>p2>>val;
        grid.push_back({p1,p2,val});
    }
    cin>>src>>dst>>k;
    vector<int> minDist(n+1,INT_MAX);
    minDist[src]=0;
    vector<int> minDist_copy(n+1);
    for(int i=1;i<=k+1;i++)
    {
        minDist_copy = minDist;
        for(vector<int> &side:grid)
        {
            int from=side[0];
            int to=side[1];
            int price=side[2];
            if(minDist_copy[from]!=INT_MAX&&minDist[to]>minDist_copy[from]+price)
                minDist[to]=minDist_copy[from]+price;
        }
    }
    if(minDist[dst]==INT_MAX) cout<<"unreachable"<<endl;
    else cout<<minDist[dst]<<endl;
}

Bellman_ford算法思维导图汇总

在这里插入图片描述

标签:运输成本,int,城市,Bellman,ford,算法,minDist,回路,负权
From: https://blog.csdn.net/2402_84438596/article/details/143025038

相关文章

  • 从单细胞和空间转录组学推断模式驱动的细胞间流动(Flowsig)--生信算法笔记
    **Inferringpattern-drivingintercellularflowsfromsingle-cellandspatialtranscriptomics**Almet,A.A.,Tsai,YC.,Watanabe,M.etal.Inferringpattern-drivingintercellularflowsfromsingle-cellandspatialtranscriptomics.NatMethods21,1806......
  • 大数据传播模型与算法——影响力最大化
    【大数据网络传播模型和算法-陈卫】——影响力最大化【持续更新】本人当前研究方向为影响力最大化(基于机器学习的组合优化算法)。目前在学习陈卫编著的《大数据传播模型与算法》,该系列会定期分享影响力最大化的学习内容(持续更新…),希望大家能够一起交流学习!前言什么是影响?......
  • 【关联规则挖掘算法‌】基于模式增长的关联规则挖掘算法
    目录一、基于模式增长的关联规则挖掘算法概述二、基于模式增长的关联规则挖掘算法优缺点和改进2.1  基于模式增长的关联规则挖掘算法优点2.2  基于模式增长的关联规则挖掘算法缺点2.3  基于模式增长的关联规则挖掘算法改进三、基于模式增长的关联规则挖掘算法编程......
  • 雪花算法------用于生成数据库中的主键、消息队列的消息ID等的算法-----算法特点,id结
    雪花算法(SnowflakeAlgorithm)是一种由Twitter公司开发的分布式ID生成算法,用于在分布式系统中生成全局唯一的ID。这种算法非常适合需要高并发、低延迟以及大量唯一ID生成的应用场景,比如数据库中的主键、消息队列的消息ID等。雪花算法的主要特点包括:唯一性:生成的ID在全球范围内......
  • 算法
    1.常见算法点击查看代码*冒泡排序:重复数列,一次比较两个元素,如果顺序错误就交换*选择排序:每次选择未排序的部分最大或最小元素,放到已排序末尾*插入排序:将未排序的元素逐个插入到已排序部分的合适位置*快速排序:选择一个基准元素,将小于的放左边,大的放右边,再对左右递归进行......
  • 图论中的最小生成树算法
    错题考察的知识点是图论中的最小生成树算法,特别是Prim算法和Kruskal算法。这两种算法都是用来寻找无向连通图中的最小生成树的。最小生成树是指连接图中所有顶点的边的集合,且这些边的总权重最小,同时保证任意两个顶点之间都是连通的。Prim算法:原理:从一个任意顶点开始,逐步增加新......
  • 基于BP神经网络的CoSaMP信道估计算法matlab性能仿真,对比LS,OMP,MOMP,CoSaMP
    1.算法仿真效果matlab2022a仿真结果如下(完整代码运行后无水印):   仿真操作步骤可参考程序配套的操作视频。 2.算法涉及理论知识概要        LS估计法实现方式较为简单,其估计过程没有考虑实际信道的噪声因素。因此,特别当毫米波MIMO信道干扰较大时,其估计性能较......
  • 常用手撕非算法题
    一.带定时器和锁的LRU缓存#include<iostream>#include<unordered_map>#include<chrono>#include<mutex>#include<thread>usingnamespacestd;classLRUCache{public:typedefstructNode{//双向链表节点intkey;//在哈希中的键值,用......
  • 代码随想录算法训练营第二天|209长度最小的子数组、59螺旋矩阵
    1leetcode209长度最小的子数组题目链接:209.长度最小的子数组文章链接:代码随想录(programmercarl.com)视频链接:拿下滑动窗口!|LeetCode209长度最小的子数组思路:没有思路,看到这道题有一种想立马退出的感觉,无从下手1.1暴力搜索1.1.1python版本这个版本的新知识就是定义......
  • JVM系列(九) -垃圾对象的回收算法介绍
    一、摘要在之前的文章中,我们介绍了JVM内部布局、对象的创建过程以及运行期的相关优化手段。今天通过这篇文章,我们一起来了解一下对象回收的判定方式以及垃圾对象的回收算法等相关知识。二、对象回收判定方式当一个对象被创建时,虚拟机会优先分配到堆空间中,当对象不再被......