代码随想录算法训练营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])
相关推荐
Yuroo zhou21 分钟前
破空驭风,智领未来 --5KG物流配送无人机展示飞行!
人工智能·算法·机器人·硬件工程·无人机
CoovallyAIHub29 分钟前
ICCV 2025 最佳论文出炉:CMU 团队用「AI 积木大师」BrickGPT 摘得桂冠!
深度学习·算法·计算机视觉
喜欢吃燃面34 分钟前
算法中的链表结构
开发语言·c++·学习·算法
Juan_201244 分钟前
P1041题解
c++·算法·题解·搜索
晨非辰1 小时前
【数据结构入坑指南】--《层序分明:堆的实现、排序与TOP-K问题一站式攻克(源码实战)》
c语言·开发语言·数据结构·算法·面试
hansang_IR2 小时前
【题解】P2217 [HAOI2007] 分割矩阵 [记忆化搜索]
c++·数学·算法·记忆化搜索·深搜
Voyager_43 小时前
算法学习记录03——二叉树学习笔记:从两道题看透后序位置的关键作用
笔记·学习·算法
我搞slam8 小时前
快乐数--leetcode
算法·leetcode·哈希算法
WWZZ20259 小时前
快速上手大模型:机器学习3(多元线性回归及梯度、向量化、正规方程)
人工智能·算法·机器学习·机器人·slam·具身感知
东方佑10 小时前
从字符串中提取重复子串的Python算法解析
windows·python·算法