代码随想录算法训练营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])
相关推荐
一匹电信狗5 小时前
【LeetCode_547_990】并查集的应用——省份数量 + 等式方程的可满足性
c++·算法·leetcode·职场和发展·stl
鱼跃鹰飞6 小时前
Leetcode会员尊享100题:270.最接近的二叉树值
数据结构·算法·leetcode
梵刹古音7 小时前
【C语言】 函数基础与定义
c语言·开发语言·算法
筵陌7 小时前
算法:模拟
算法
We་ct8 小时前
LeetCode 205. 同构字符串:解题思路+代码优化全解析
前端·算法·leetcode·typescript
renhongxia18 小时前
AI算法实战:逻辑回归在风控场景中的应用
人工智能·深度学习·算法·机器学习·信息可视化·语言模型·逻辑回归
CoderCodingNo8 小时前
【GESP】C++四级/五级练习题 luogu-P1223 排队接水
开发语言·c++·算法
民乐团扒谱机8 小时前
【AI笔记】精密光时频传递技术核心内容总结
人工智能·算法·光学频率梳
CoderCodingNo8 小时前
【GESP】C++五级/四级练习题 luogu-P1413 坚果保龄球
开发语言·c++·算法
2301_822366359 小时前
C++中的命令模式变体
开发语言·c++·算法