题目
光明小学的小朋友们要举行一年一度的接力跑大赛了,但是小朋友们却遇到了一个难题:设计接力跑大赛的线路,你能帮助他们完成这项工作么?
光明小学可以抽象成一张有N个节点的图,每两点间都有一条道路相连。光明小学的每个班都有M个学生,所以你要为他们设计出一条恰好经过M条边的路径。
光明小学的小朋友们希望全盘考虑所有的因素,所以你需要把任意两点间经过M条边的最短路径的距离输出出来以供参考。
你需要设计这样一个函数:
res[][] Solve( N, M, map[][]);
注意:map必然是N * N的二维数组,且map[i][j] == map[j][i],map[i][i] == 0,-1e8 <= map[i][j] <= 1e8。(道路全部是无向边,无自环)2 <= N <= 100, 2 <= M <= 1e6。要求时间复杂度控制在O(N^3*log(M))。
map数组表示了一张稠密图,其中任意两个不同节点i,j间都有一条边,边的长度为map[i][j]。N表示其中的节点数。
你要返回的数组也必然是一个N * N的二维数组,表示从i出发走到j,经过M条边的最短路径
你的路径中应考虑包含重复边的情况。
样例:
N = 3
M = 2
map = {
{0, 2, 3},
{2, 0, 1},
{3, 1, 0}
}
输出结果result为:
result = {
{4, 4, 3},
{4, 2, 5},
{3, 5, 2}
}
输入样例:
3
2
3 3
0 2 3
2 0 1
3 1 0
输出样例:
[[4, 4, 3],
[4, 2, 5],
[3, 5, 2]]
代码思路:首先很气,编出主程序的时候,在输入数据处理上,遇到很白痴的问题,结果没有来得及改就胶卷了,完成之后花了2min改好,上传上来
采用动态规划的方式来做
import numpy as np
def Solve(maps,M):
'''
由N个节点两两连接组成路径,选取从节点i->节点j之间的最短M条路径
param:
maps:二维数组,由两两节点之间的路径长度组成
M:表示所经过的路径个数
'''
'''
输入校验
'''
if not isinstance(maps,(list,np.ndarray)):
raise ValueError('输入参数maps数据类型必须是list或者numpy.array')
if len(maps.shape) != 2:
raise ValueError('输入参数maps为二维数组')
if maps.shape[0] != maps.shape[1]:
raise ValueError('输入二维数组maps行数和列数要求一致')
#计算节点的个数
N = maps.shape[0]
if N<2 or N>100:
raise ValueError('输入二维数组maps行数必须在2~100之间')
if M<2 or M>1E6:
raise ValueError('输入参数N的值必须在2~1e6之间')
#输入二维数组数值校验
for i in range(N):
for j in range(i,N):
if maps[i][j] != maps[j][i]:
raise ValueError('输入二维数组maps必须是对称的')
if maps[i][j] < -1e8 or maps[i][j] > 1e8:
raise ValueError('二维数组maps的元素值必须在-1e8~1e8之间')
if i==j:
if maps[i][j] != 0:
raise ValueError('二维数组maps的对角元素值必须是0')
#用于保存i->j的路径值
res = np.zeros_like(maps)
#计算节点i->j的最短路径
for i in range(N):
for j in range(i,N):
res[i][j] = MinPath(maps,M,i,j)
res[j][i] = res[i][j]
return res
def MinPath(maps,M,i,j):
'''
计算i->j的最短路径
'''
#递归终止条件
if M == 1:
return maps[i][j]
'''计算i->j的最短路径'''
N = maps.shape[0]
#用于保存i->j的可能路径长度
length = np.zeros(N)
#遍历从k->j的最短路径
for k in range(N):
if k != i and k != j:
#k->j的M-1条最短路径 + i->k的一条路径
length[k] = MinPath(maps,M-1,k,j) + maps[i][k]
#进行排序,过滤掉为0的值
length = np.sort(length)
for i in length:
if i != 0:
return i
if __name__ == '__main__':
N = int(input().strip())
M = int(input().strip())
shapes = [int(c) for c in input().strip().split()]
#print(shapes)
maps = []
for i in range(N):
n = [int(c) for c in input().strip().split()]
maps.append(n)
#print(maps)
maps = np.array(maps)
result = Solve(maps,M)
print(result)