看数据范围可知,时间复杂度一定小于(n**4),暴力求解肯定不行。
题目要求,求出任意两个点之间最小距离的和,那么想到Folyd算法,但是这个算法需要(n**3),并且题目询问n次,总共需要(n**4),那么想到一个一个删除点再求最小距离,相对于一个一个加点,再求最小和,跟Folyd算法流程不谋而合,例如前面有a,b点,先需要加上c点,那么这次把c当做路过的点,计算a到c再到b的距离,和原来a到b的距离进行比较。
有问题,有问题。如果这时候又加上了d点,重复上述流程,把d点当做路过的点,计算a到d再到b,a到d再到c......。看似没问题,之前是不是忘记一步?
少了从a,b经过c再到d,和d经过c再到a,b。上一步需要把所有的点经过c再到另一个点,而不是只计算a,b经过c到另一个点。
from collections import defaultdict
def floyd(ls):
new = ls[-1]
for i in range(n):
for j in range(n):
edge[i][j] = min(edge[i][j], edge[i][new] + edge[new][j] )
count = 0
for i in ls:
for j in ls:
count += edge[i][j]
ans.append(count)
# 编号从0-n-1
# 那么x-1才为我们的编号
edge = []
v = defaultdict(int)
n = int(input())
for _ in range(n):
edge.append(list(map(int, input().split())))
questions = list(map(int, input().split()))
ans = []
ls = []
for num in questions[::-1]:
ls.append(num-1)
floyd(ls)
for num in ans[::-1]:
print(num, end = ' ')