AcWing 91. 最短Hamilton路径
原题链接
中等
作者:
Actor丶
,
2020-02-03 22:20:51
,
所有人可见
,
阅读 543
"""
基本思想:(n个节点,则用0~((1<<n)-1)的所有整数表示经过的所有路径)
1. 状态表示:
1.1 集合f[i,j]:表示从节点0到节点j,且经过的所有点是路径i(二进制数)的路径
1.2 属性:Min,即从0开始到节点(n-1)的路径的最短长度
2. 状态计算(状态转移方程,根据选择第i个数的次数是0,1...s,进行划分):
f[i][j] = min(f[i][j], f[i-{j节点}][k]+a[k][j]), k=0,1,2,...,n-1
"""
# 1. 输入示例
n = int(input().strip())
a = []
for i in range(n):
a.append(list(map(int,input().split())))
# 2. 初始化dp数组
dp = [[float("inf") for i in range(n)] for j in range(1<<n)] # 属性是求最小值,所以dp数组元素初始化为inf
dp[1][0] = 0 # 从第0号点到第0号点,经过第1号点的路径在最短路径长度为0
# 3. 状态计算
for i in range(1<<n): # 遍历在从第0号点到第j号点时,可能经过的所有节点组成的路径
for j in range(n): # 遍历所有路径可能结尾的点[0~n-1]
if (i>>j) & 1: # 如果路径i以第j号点结尾
for k in range(n): # 遍历以第j号点结尾的路径i的倒数第二个点的编号k
if (i-(1<<j)) >> k & 1: # 如果路径i删除节点j后,倒数第二个节点为k,则执行状态转移方程
dp[i][j] = min(dp[i][j], dp[i-(1<<j)][k]+a[k][j])
print(dp[(1<<n)-1][n-1])