赞
踩
发现可以使用滚动数组优化第一维度:
枚举所有k,判断是否可以作为中间点,可以作为中间点则优化最短路。
初始化:如果<i, j>无边,则dp[i][j] = INF, 有边则等于边权;dp[i][i] = 0(自己到自己是不用走的)
为了理解更深刻,简单举个例子:
各点之间的关系用邻接矩阵保存(下图中又两个邻接矩阵,一个是两点之间的最短距离,还有一个是两点之间的最短路中经过的节点。)
更新
每次基于之前能找到的最短路径,如果比它短就更新。
以2号节点作为中转站是基于1号节点作为中转站的,经过n轮递推就可以得到最终答案(任意两点的最短路)
为什么先遍历k,之后遍历i,j?
因为要符合顺序,遍历完中间点后, 就要遍历邻接矩阵,进行最短距离的更新。
- import os
- import sys
-
- # 请在此输入您的代码
- n, m, q = map(int, input().split())
- INF = 10 ** 18
- # dp[i][j]表示i到j的最短路
- dp = [[INF] * (n + 1) for i in range(n + 1)] # 初始值设较大值
- for i in range(1, n + 1):
- dp[i][i] = 0 # 自己到自己的距离为0
- for _ in range(m):
- u, v, w = map(int, input().split())
- dp[u][v] = dp[v][u] = min(dp[u][v], w) # 双向边/无向边(可能有重边)
-
- # Floyd算法模板
- # dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j])
- for k in range(1, n + 1):
- for i in range(1, n + 1):
- for j in range(1, n + 1):
- dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j])
-
- for _ in range(q):
- u, v = map(int, input().split())
- if dp[u][v] == INF:
- print(-1)
- else:
- print(dp[u][v])
- import os
- import sys
-
- # 请在此输入您的代码
- """
- 翻译题意:有n个城市,m条边就是有m条路径可以流通,每个城市有自己的商品产出,可以拿去别的地方销售,
- 需要求出最大利润,但是商品产量ai是不变的,生产成本pi也是不变的,只有售卖单价会随着商品运输到其他
- 城市会改变,以及带来的运输费用(这里的运输费用有一个路径的问题,需要用最短路算出来最少支付。
- """
-
- n, m = map(int, input().split())
- # g = s - p - f(路径费用)
- INF = 10 ** 17
- a, p, s = [0] * (n + 1), [0] * (n + 1), [0] * (n + 1) # 商品的产量, 生产成本, 售卖单价
- f = [[INF] * (n + 1) for i in range(n + 1)] # 记录最短路(也就是最短的运输费用)
- g = [[0] * (n + 1) for i in range(n + 1)] # 记录利润
- for i in range(1, n + 1):
- a[i], p[i], s[i] = map(int, input().split())
- for _ in range(1, m + 1):
- u, v, w = map(int, input().split())
- f[u][v] = f[v][u] = min(f[u][v], w)
- for i in range(1, n + 1):
- f[i][i] = 0
-
- for k in range(1, n + 1):
- for i in range(1, n + 1):
- for j in range(1, n + 1):
- f[i][j] = min(f[i][k] + f[k][j], f[i][j])
- # g[i][j]表示城市1的物品运输到城市j可得的利润=城市j的售价-城市i的成本-运输f[i][j]
- for i in range(1, n + 1):
- for j in range(1, n + 1):
- g[i][j] = s[j] - p[i] - f[i][j]
- ans = 0
- for i in range(1, n + 1):
- # 遍历每个城市的商品
- now_ans = 0
- # 遍历移动到的城市(包括自己本身)
- for j in range(1, n + 1):
- now_ans = max(now_ans, a[i] * g[i][j])
- ans += now_ans # 记录每个城市的利润
-
- print(ans)
作用:处理非负权边的单源最短路问题
利用贪心+动态规划思想,实现从源点s出发到所有点的最短距离
核心思想:从起点出发,每次选择距离最短的点进行”松弛”操作
算法步骤:
1.将起点入队列,d数组表示从起点s出发到达每个最短距离
2.不断取出队列中距离最小的点u,进行“松弛”:
对于从u到v,权重为w的边
正在更新中...
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。