【ACWing算法题】最短路径算法之dirjkstra单源最短路径模板

学习导图:

37ff39642fd8f74476ddcd99944d1b4.png

目录

【模板】单源最短路径

参考题解

【蓝桥真题】单源最短路径

参考题解:


【模板】单源最短路径

亲,题目链接请戳这里

题目描述 

        给定一个n个点,m条有向边的带非负权图,请你计算从s出发,到每个点的距离。

数据保证你能从s出发到任意点。

 输入格式

        第一行为三个正整数n, m,s。第二行起m行,每行三个非负整数uL;, u;, u;,表示从u;到v;有一条权值为w;的有向边。

 输出格式

输出一行n个空格分隔的非负整数,表示s到每个点的距离。

 

参考题解

import heapq
from collections import defaultdict
# 核心代码
def dirjkstra():
    # 各节点到start的最短距离
    dirs = [float('inf')] * (n + 1)
    dirs[start] = 0

    # 已用节点,比set还快20% 所有没有释放False
    seen = [False] * (n + 1)

    pq = []
    heapq.heappush(pq, (0, start))

    # BFS
    while pq:
        # 获取
        _, u = heapq.heappop(pq)
        
        # 该节点是否用过
        if seen[u]:
            continue
        else:
            seen[u] = True

        # 找到邻接节点
        nodeList = graph[u]
        for v, w in nodeList:
            t = dirs[u] + w
            if t < dirs[v]:
                dirs[v] = t
                # 如果该邻接节点没有访问过才把该最短边加进去
                if not seen[v]:
                    heapq.heappush(pq, (t, v))
                
    if dirs[-1] == float('inf'):
        return -1
    else:
        return dirs[-1]
    
# 输入
n, m = map(int, input().split())

# 初始化
start = 1

# 建图
graph = defaultdict(list)
for _ in range(m):
    u, v, w = map(int, input().split())
    graph[u].append((v,w))

answer = dirjkstra()
print(answer)


【蓝桥真题】单源最短路径

试题:路径

本体总分:10分

【问题描述】        

        小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图中的最短路径。

        小蓝的图由 2021个结点组成,依次编号1至2021。

        对于两个不同的结点a, b,如果a和b的差的绝对值大于21,则两个结点之间没有边相连;如果a和b的差的绝对值小于等于21,则两个点之间有一条长度为a和 b的最小公倍数的无向边相连。

        例如:结点1和结点23之间没有边相连;结点3和结点24之间有一条无向边,长度为24;结点15和结点25之间有一条无向边,长度为75。

        请计算,结点1和结点2021之间惘最短路径长度是多少?

        提示:建议使用计算机编程解决问题。

参考题解:(答案:10266837)

import heapq
from collections import defaultdict

def gcd(a, b):
    if a < b:
        a, b = b, a

    if a % b == 0:
        return b
    else :
        return gcd(b, a%b)

def lcm(a, b):
    return int(a * b / gcd(a, b))

n = 2021
MAX_SIZE = n + 1

def init_graph():
    graph = defaultdict(list)
    for i in range(1, 2022):
        for j in range(1, 2022):
            if abs(i-j) <= 21:
                if i == j :
                    continue
                else:
                    graph[i].append([j, lcm(i, j)])

    return graph


graph = init_graph()
def dirjkstra(start):
    dirs = [float('inf')] * MAX_SIZE
    dirs[start] = 0

    seen = [False] * MAX_SIZE

    pq = []
    heapq.heappush(pq, (0, start))

    while pq:
        _, u = heapq.heappop(pq)
        
        if seen[u]:
            continue
        else:
            seen[u] = True

        edgeList = graph[u]
        for v, w in edgeList:
            t = dirs[u] + w
            if t < dirs[v]:
                dirs[v] = t

                if not seen[v]:
                    heapq.heappush(pq, (t, v))
                    
    return dirs

dirs = dirjkstra(1)
print(dirs[2021])
# 10266837
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大气层煮月亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值