代码随想录算法训练营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])
相关推荐
mashanshui3 小时前
Https之(二)TLS的DH密钥协商算法
算法·https·tls·dh·ecdhe
wearegogog1236 小时前
MATLAB的脉搏信号分析预处理
算法·matlab
fs哆哆6 小时前
在VB.net中一维数组,与VBA有什么区别
java·开发语言·数据结构·算法·.net
wjt1020206 小时前
机器学习--续
算法·机器学习
牵星术小白7 小时前
【GNSS基带算法】Chapter.2 相干积分与非相干积分
算法
哇哈哈QIQ8 小时前
2025.7.19卡码刷题-回溯算法-组合
算法
gihigo199810 小时前
matlab多目标优化差分进化算法
数据结构·算法
weixin_5824701711 小时前
GS-IR:3D 高斯喷溅用于逆向渲染
人工智能·算法
Lin9成11 小时前
机器学习集成算法与K-means聚类
算法
JNU freshman12 小时前
算法 之 拓 扑 排 序
数据结构·算法