代码随想录算法训练营day74 | 94. 城市间货物运输 I、95. 城市间货物运输 II、96. 城市间货物运输 III

本次题目全部来自卡码网

94. 城市间货物运输 I(Bellman_ford 队列优化算法)

bellman_ford使用队列优化

python 复制代码
import collections

class Edge:
    def __init__(self, to, val):
        self.to = to  # 链接的节点
        self.val = val  # 边的权重


if __name__ == '__main__':
    n, m = map(int, input().split())
    grid = [[] for _ in range(n + 1)]  # 邻接表
    for i in range(m):
        p1, p2, val = map(int, input().split())
        grid[p1].append(Edge(p2, val))

    start = 1  # 起点
    end = n  # 终点

    minDist = [float('inf')] * (n + 1)
    minDist[start] = 0

    que = collections.deque()
    que.append(start)  # 队列里放入起点

    while que:
        node = que.popleft()
        for edge in grid[node]:
            _from = node
            to = edge.to
            value = edge.val
            if minDist[to] > minDist[_from] + value:
                minDist[to] = minDist[_from] + value
                que.append(to)

    if minDist[end] == float('inf'):
        print('unconnected')
    else:
        print(minDist[end])

95. 城市间货物运输 II(bellman_ford之判断负权回路)

检测负权回路

之前讲过的两种做法都能

第一种:松弛n-1次之后继续松弛,最短距离有变化,说明有负权回路,代码超时

第二种:加入队列>=n次,说明有负权回路

第一种

python 复制代码
if __name__ == '__main__':
    n, m = map(int, input().split())
    grid = []
    for i in range(m):
        p1, p2, val = map(int, input().split())
        grid.append((p1, p2, val))

    start = 1  # 起点
    end = n  # 终点

    minDist = [float('inf')] * (n + 1)
    minDist[start] = 0
    flag = False
    for i in range(n):  # 松弛n次,最后一次判断距离是否有变化
        for side in grid:  # 每一次松弛,都是对所有边进行松弛
            _from = side[0]  # 边的出发点
            to = side[1]  # 边的到达点
            price = side[2]  # 边的权值
            # 松弛操作
            # minDist[from] != INT_MAX 防止从未计算过的节点出发
            if i < n - 1:
                if minDist[_from] != float('inf') and minDist[to] > minDist[_from] + price:
                    minDist[to] = minDist[_from] + price
            else:
                if minDist[_from] != float('inf') and minDist[to] > minDist[_from] + price:
                    flag = True

    if flag:
        print('circle')
    elif minDist[end] == float('inf'):
        print("unconnected")  # 不能到达终点
    else:
        print(minDist[end])  # 到达终点最短路径

第二种

python 复制代码
import collections

class Edge:
    def __init__(self, to, val):
        self.to = to  # 链接的节点
        self.val = val  # 边的权重


if __name__ == '__main__':
    n, m = map(int, input().split())
    grid = [[] for _ in range(n + 1)]  # 邻接表
    for i in range(m):
        p1, p2, val = map(int, input().split())
        grid[p1].append(Edge(p2, val))

    start = 1  # 起点
    end = n  # 终点

    minDist = [float('inf')] * (n + 1)
    minDist[start] = 0
    count = [0] * (n + 1)
    flag = False

    que = collections.deque()
    que.append(start)  # 队列里放入起点
    count[start] += 1

    while que:
        node = que.popleft()
        for edge in grid[node]:
            _from = node
            to = edge.to
            value = edge.val
            if minDist[to] > minDist[_from] + value:
                minDist[to] = minDist[_from] + value
                que.append(to)
                count[to] += 1
                if count[to] == n:
                    flag = True
                    print("circle")
                    exit()

    if minDist[end] == float('inf'):
        print('unconnected')
    else:
        print(minDist[end])

96. 城市间货物运输 III(bellman_ford之单源有限最短路)

至于经过k个节点

下面代码超时

python 复制代码
if __name__ == '__main__':
    n, m = map(int, input().split())
    grid = []
    for i in range(m):
        p1, p2, val = map(int, input().split())
        grid.append((p1, p2, val))

    src, dst, k = map(int, input().split())

    minDist = [float('inf')] * (n + 1)
    minDist[src] = 0

    for i in range(k + 1):
        minDist_copy = minDist[:]  # 获取上一次计算的结果
        for side in grid:
            _from = side[0]
            to = side[1]
            price = side[2]
            # 注意使用 minDist_copy 来计算 minDist
            if minDist_copy[_from] != float('inf') and minDist[to] > minDist_copy[_from] + price:
                minDist[to] = minDist_copy[_from] + price

    if minDist[dst] == float('inf'):
        print("unreachable")  # 不能到达终点
    else:
        print(minDist[dst])  # 到达终点最短路径

下面代码可通过

python 复制代码
import collections


class Edge:
    def __init__(self, to, val):
        self.to = to  # 链接的节点
        self.val = val  # 边的权重


if __name__ == '__main__':
    n, m = map(int, input().split())
    grid = [[] for _ in range(n + 1)]  # 邻接表
    for i in range(m):
        p1, p2, val = map(int, input().split())
        grid[p1].append(Edge(p2, val))

    start, end, k = map(int, input().split())
    k += 1

    minDist = [float('inf')] * (n + 1)
    minDist[start] = 0
    flag = False

    que = collections.deque()
    que.append(start)  # 队列里放入起点

    while k != 0 and que:
        visited = [False] * (n + 1)  # 每一轮松弛中,控制节点不用重复入队列
        minDist_copy = minDist[:]  # 用来记录每一次遍历的结果
        que_size = len(que)
        for _ in range(que_size):
            node = que.popleft()
            for edge in grid[node]:
                _from = node
                to = edge.to
                value = edge.val
                if minDist[to] > minDist_copy[_from] + value:
                    minDist[to] = minDist_copy[_from] + value
                    if visited[to]:  # 不用重复放入队列,但需要重复松弛,所以放在这里位置
                        continue
                    visited[to] = True
                    que.append(to)
        k -= 1

    if minDist[end] == float('inf'):
        print('unreachable')
    else:
        print(minDist[end])
相关推荐
_.Switch8 分钟前
Python机器学习模型的部署与维护:版本管理、监控与更新策略
开发语言·人工智能·python·算法·机器学习
自由的dream1 小时前
0-1背包问题
算法
2401_857297911 小时前
招联金融2025校招内推
java·前端·算法·金融·求职招聘
良月澪二3 小时前
CSP-S 2021 T1廊桥分配
算法·图论
wangyue44 小时前
c# 线性回归和多项式拟合
算法
&梧桐树夏4 小时前
【算法系列-链表】删除链表的倒数第N个结点
数据结构·算法·链表
QuantumStack4 小时前
【C++ 真题】B2037 奇偶数判断
数据结构·c++·算法
今天好像不上班4 小时前
软件验证与确认实验二-单元测试
测试工具·算法
wclass-zhengge5 小时前
数据结构篇(绪论)
java·数据结构·算法
何事驚慌5 小时前
2024/10/5 数据结构打卡
java·数据结构·算法