问题描述
逗志芃是有妹子的现充,但是有时候妹子就是烦恼。因为逗志芃太逗了,所以这段时间妹子对逗志芃发动了技能无理取闹,妹子要去玩很多的景点。由于逗志芃之前抽机花费了太多的时间,不久以后又要微积分考试了,所以现在被妹子搞成暴走状态了。但是妹子永远是上帝,所以逗志芃只能带妹子出去玩,不过为了节约时间,他希望找到一条花费时间最少的一次性游览线路。
输入格式
第一行1个数n,表示逗志芃所在的城市有多少个景点,接下来是一个n*n的矩阵。a(i,j)表示i号景点到j号景点的路上花费的时间是多少。
接下来是一个数m,表示逗志芃妹子要去去的景点数目。由于妹子在无理取闹,所以可能会有重复的景点,不过只要去一次就可以了。接下来是m个数,就是妹子要去的景点编号。
输出格式
一个数,最少的花费时间。
样例输入
3
0 1 2
1 0 3
2 3 0
3
2 3 1
样例输出
3
数据规模和约定
0<n<=30,0<m<=20,时间<=1000000
思路:先用F算法算出每端到其他端的最短距离,再将要去的景点求全排列,求出每一个排列的距离,再找出最短距离
import itertools
n=int(input())
spots=[list(map(int,input().split()))for i in range(n)]
m=int(input())
scenics=list(map(int,input().split()))
scenics=list(set(scenics))
def F(lst,n):#F算法,求多端到多端之间的最短距离
for time in range(n):
for i in range(n):
if i!=time:
for j in range(n):
if j!=time:
if lst[time][i]+lst[j][time]<lst[i][j]:
lst[i][j]=lst[time][i]+lst[j][time]
return lst
new=F(spots,n)# 已求的多端到多端之间的最短距离
time=[]
ed=[]
for scenic in itertools.permutations(scenics):#求全排列
if scenic[0] not in ed:
ed.append(scenic[0])
if scenic[0]==scenics[-1]:
break
elif scenic[-1] in ed:#从左往右数和从右往左数一样,去重
continue
else:
temp=0
for i in range(len(scenic)-1):
a=scenic[i]-1
b=scenic[i+1]-1
temp+=new[a][b]
time.append(temp)
print(min(time))