菜鸟笔记-python例题(13)

文章介绍了一个使用Python实现的SPFA算法,该算法用于计算图中的最短路径。代码中定义了Edge类来表示边,通过全局变量维护图的结构,并利用队列进行广度优先搜索。程序处理特定的输入序列,构建图并计算从源点到各节点的最短距离,最后输出结果序列。
摘要由CSDN通过智能技术生成

题目描述

买菜

(1)问题描述及输入输出式要求 问题描述要求如 1.13.1-1

输入输出格式要如下图

(2)解题思路分析

  1. 首先始化全局变量cur(当前的数量)、head(个节点 的第一条边)、edge保存所有边的信同时声明 spfa 函数使  SPFAShortest Path Faster Algorithm短路径快速算)算法 计算特定数值。
  2. 根据所给整数序护图的边于序列 a 中的每个元素加对 应的边,连接相的节点和特定权之间的关系。
  3. 调用 spfa 函数。这个函数中,首先使用队 qq 存储每个节, 然后初始化 vis(标记当前点是否在队列中标志数组dist 节点的最短距离数组和 inq(每个节点进入列的次数)数 4.在 SPFA 算法中,遍队列中所有节点计算它们的最途径并更新dist 数组。如果一节点进入队列次数多于 n 次,输出 “noanswer 并终止程序
  4. 使用 SPFA 计算出的 dist 数组,构建最终的 b 序列。将结果储在 数组 a 中,便于出。

(3)提交的编程代码

from collections import deque
class Edge:
 def __init__(self, to, next, v):
     self.to = to
     self.next = next
     self.v = v


def addedge(x, y, v):
 global cur, head, edge
 edge[cur] = Edge(y, head[x], v)
 head[x] = cur
 cur += 1


def spfa():
 global n, dist, inq, vis, head, edge
 qq = deque(range(n + 1))
 vis = [1] * (n + 1)
 dist = [0] * (n + 1)
 inq = [1] * (n + 1)
 
while qq:
     x = qq.popleft()
     inq[x] += 1
     vis[x] = 0
     if inq[x] > n:
         print("noanswer")
         return


 i = head[x]
 while i != -1:
     nx = edge[i].to
     if dist[nx] < dist[x] + edge[i].v:
     dist[nx] = dist[x] + edge[i].v
     if not vis[nx]:
         vis[nx] = 1
         qq.append(nx)
    i = edge[i].next
 return
def main():
 global cur, head, edge, n, a
 cur = 0
 n = int(input())
 head = [-1] * (n + 1)
 edge = [None] * 2006
 a = [0] + list(map(int, input().split()))
 

for i in range(n - 2):
     addedge(i + 3, i, -(a[i + 2] * 3 + 2))
     addedge(i, i + 3, a[i + 2] * 3)
addedge(2, 0, -(a[1] * 2 + 1))
addedge(0, 2, a[1] * 2)
addedge(n, n - 2, -(a[n] * 2 + 1))
addedge(n - 2, n, a[n] * 2)
for i in range(1, n + 1):
     addedge(i - 1, i, 1)
spfa()
a[1] = dist[1]
for i in range(2, n + 1):
    a[i] = dist[i] - dist[i - 1]
    print(a[1], end="")
for i in range(2, n + 1):
    print(" " + str(a[i]), end="")
if __name__ == "__main__":
 main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值