代码随想录算法训练营第六十五天| 图论10—卡码网94. 城市间货物运输 I,95. 城市间货物运输 II

被学校课程轰炸了一周,回过头发现训练营已经要结束了,抓紧时间补完。不过算法这边也很难,感觉每天都是勉强理解在干什么的状态。

94. 城市间货物运输 I

94. 城市间货物运输 I

SPFA算法,也是Bellman_ford 队列优化算法

优化原理:Bellman_ford 算法 每次都是对所有边进行松弛,其实是多做了一些无用功。只需要对上一次松弛的时候更新过的节点作为出发节点所连接的边进行松弛就够了。

其实感觉和Bellman_ford算法比较像,核心思想还是去做松弛。优化的点具体来说有两个,一是使用队列来只更新最短路径发生改变的节点,用visited来标记避免重复入队,也就是多了个全为FALSE的visited数组来进行统计,在图论题目中还是很常见的。另一个就是加入if minDistcur + weight < minDistdest:多一个判断语句去更新最短路径。

python 复制代码
import collections

def main():
    n, m = map(int, input().strip().split())
    edges = [[] for _ in range(n + 1)]
    for _ in range(m):
        src, dest, weight = map(int, input().strip().split())
        edges[src].append([dest, weight])
    
    minDist = [float("inf")] * (n + 1)
    minDist[1] = 0
    que = collections.deque([1])
    visited = [False] * (n + 1)
    visited[1] = True
    
    while que:
        cur = que.popleft()
        visited[cur] = False
        for dest, weight in edges[cur]:
            if minDist[cur] != float("inf") and minDist[cur] + weight < minDist[dest]:
                minDist[dest] = minDist[cur] + weight
                if visited[dest] == False:
                    que.append(dest)
                    visited[dest] = True
    
    if minDist[-1] == float("inf"):
        return "unconnected"
    return minDist[-1]

if __name__ == "__main__":
    print(main())

95. 城市间货物运输 II

95. 城市间货物运输 II

本题主要是判断负权回路,意思就是出现环,并且环内总值相加为负数。这种情况下就可以绕着环无限循环,让权重无限减少,所以需要在代码中判断负权回路的存在并且避免无限次循环。

仍然使用SPFA算法,可以看到代码大体一样,但是最主要的是多了一句判断 if countnext_node == n: flag = True。Bellman-Ford 算法下能够保证每个点的最短路径最多只需要被更新 n - 1 次。但是当一个点的路径被更新了第 n 次,说明有环且路径还在变短必有负权环,因为再更新还能变短,就证明有一个负权环,使用count计算节点进入队列的次数。

python 复制代码
from collections import deque
from math import inf

def main():
    n, m = [int(i) for i in input().split()]
    graph = [[] for _ in range(n+1)]
    min_dist = [inf for _ in range(n+1)]
    count = [0 for _ in range(n+1)]  # 记录节点加入队列的次数
    for _ in range(m):
        s, t, v = [int(i) for i in input().split()]
        graph[s].append([t, v])
        
    min_dist[1] = 0  # 初始化
    count[1] = 1
    d = deque([1])
    flag = False
    
    while d:  # 主循环
        cur_node = d.popleft()
        for next_node, val in graph[cur_node]:
            if min_dist[next_node] > min_dist[cur_node] + val:
                min_dist[next_node] = min_dist[cur_node] + val
                count[next_node] += 1
                if next_node not in d:
                    d.append(next_node)
                if count[next_node] == n:  # 如果某个点松弛了n次,说明有负回路
                    flag = True
        if flag:
            break
            
    if flag:
        print("circle")
    else:
        if min_dist[-1] == inf:
            print("unconnected")
        else:
            print(min_dist[-1])


if __name__ == "__main__":
    main()
相关推荐
Wang's Blog5 分钟前
Vibe Coding一人即团队系列35: 基于Claude Code的Spring Boot项目初始化实践
java·spring boot·后端
Dovis(誓平步青云)22 分钟前
拍视频前先把镜头想清楚:做一个分镜取景辅助器
android·java·服务器·javascript·人工智能
AI人工智能+电脑小能手25 分钟前
大白话说Java设计模式-45-解释器模式(源码剖析篇)
java·设计模式·解释器模式·源码分析·pattern·spel·javacc
AI服务老曹36 分钟前
车牌识别算法接入AI视频分析平台的流程和误报优化
人工智能·算法·音视频
吴声子夜歌39 分钟前
Java——开发中通用的方法和准则(二)
java·开发语言·php
袁震1 小时前
HarmonyOS 应用包体积优化与上架自检实战:从 76.2MB 到 3.6MB
java·华为·性能优化·harmonyos
神威难绷泪1 小时前
Linux应用软件编程:线程分离属性 互斥机制 同步机制 死锁
linux·开发语言·算法·线程
zcmodeltech1 小时前
反应装置模型控制系统设计与实现:多设备协同联动方案
java·网络·数据库·stm32·嵌入式硬件·能源·制造
小星星闪亮登场1 小时前
图论--最小生成树(内含二分图)
数据结构·算法·图论·迭代加深·图搜索算法
码视野1 小时前
基于 Spring Boot + Vue3 的【城市地下燃气管网微泄漏感知与相邻地下空间燃爆预警中台】设计与实现(含PRD/三端高保真源码/大屏)
java·前端·人工智能·spring boot·后端