题目:光明小学的小朋友们要举行一年一度的接力跑大赛了,但是小朋友们却遇到了一个难题:设计接力跑大赛的线路,你能帮助他们完成这项工作么?
光明小学可以抽象成一张有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条边的最短路径
你的路径中应考虑包含重复边的情况。
def dfs(node,end,map,dis,min_dis,N,M,step):
if step==M-1:
if node!=end:
return dis+map[node][end] #最后一层时直接连接到目标
else:
return float('inf') #若本身就是目标,说明无法到达,判定无穷远
step=step+1
for i in range(N):
if i == node:
continue
tmp_dis=dfs(i, end, map, dis + map[node][i],min_dis, N, M, step) #每次递归结束,返回1:N到目的地的距离
if tmp_dis<min_dis: #取其最小值
min_dis=tmp_dis
return min_dis #返回最终结果
def solve(map,M):
N=len(map)
step=0
dis=0
result=[[float('inf') for i in range(N)] for j in range(N)] #初始化结果矩阵
for i in range(N): #初始化出发点
for j in range(N): #初始化目的地
min_dis = float('inf') #初始化当前最短距离
result[i][j] =dfs(i, j, map, dis,min_dis,N, M, step)
return result
map=[[0 for i in range(3)] for j in range(3)]
map[0]=[0,2,3]
map[1]=[2,0,1]
map[2]=[3,1,0]
M=2
result=solve(map,M)
print(result)
map=[[0 for i in range(4)] for j in range(4)]
map[0]=[0,2,3,4]
map[1]=[2,0,1,3]
map[2]=[3,1,0,2]
map[3]=[4,3,2,0]
M=3
result=solve(map,M)
print(result)
结果为:
[[4, 4, 3], [4, 2, 5], [3, 5, 2]]
[[6, 4, 5, 5], [4, 6, 3, 5], [5, 3, 6, 4], [5, 5, 4, 6]]
该方案为暴力递归,M层全连接层,每层有(N-1)^2的连接线,时间复杂度为O(N^M),离O(N^3*log(M))大概还差好几个最短路径的距离