题目描述
买菜
(1)问题描述及输入输出格式要求 问题描述要求如下图 1.13.1-1
输入输出格式要求如下图
(2)解题思路分析
- 首先,初始化全局变量,例如 cur(当前边的数量)、head(每个节点 的第一条边)、edge(保存所有边的信息)等;同时声明 spfa 函数,使 用 SPFA(Shortest Path Faster Algorithm,最短路径快速算法)算法 计算特定数值。
- 根据所给整数序列,维护图的边:对于序列 a 中的每个元素,添加对 应的边,连接相邻的节点和特定权值之间的关系。
- 调用 spfa 函数。在这个函数中,首先使用队列 qq 存储每个节点, 然后初始化 vis(标记当前节点是否在队列中的标志)数组,dist(每个 节点的最短距离)数组和 inq(每个节点进入队列的次数)数组。 4.在 SPFA 算法中,遍历队列中所有节点,计算它们的最短途径并更新dist 数组。如果一个节点进入队列的次数多于 n 次,输出 “noanswer” 并终止程序
- 使用 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()