给定n个城市(从0到n-1),3元组[A, B, C]表示城市A和城市B之间存在道路,且成本为C。计算从0号城市出发,旅行完每个城市一遍,最后回到0号城市的最小成本与路径。如果不存在最优方案,输出-1. 【输入形式】 第一行有两个数n、m表示n个城市,m条边。 接下来的m行均为空格隔开的三个整数A B C,表示城市A和B之间的成本为C 【输出形式】 最小成本 最小成本对应的路径 的实验报告
时间: 2024-02-11 08:03:58 浏览: 28
本次实验我们学习了旅行商问题的解法。旅行商问题是指给定一些城市和每对城市之间的距离,求解访问每个城市恰好一次并回到起始城市的最短回路。这是一个NP难问题,无法在多项式时间内求解,因此我们需要使用类似动态规划的方法来解决。
我们先介绍一下旅行商问题的状态转移方程。设dp[S][i]表示已经经过集合S中的城市,最后到达城市i的最小成本。则可以得到状态转移方程:
dp[S|{i}][i] = min(dp[S][j] + cost[j][i]),其中j∈S,cost[j][i]表示从城市j到城市i的成本。
其中S|{i}表示将城市i加入集合S中,j∈S表示已经经过的城市集合。这个状态转移方程可以用一个二维数组dp来表示。
接下来我们来看看完整的Python代码实现。代码实现上,我们需要读入城市数n和边数m,然后对于每条边,将起点和终点之间的距离存入一个二维的cost数组中。接着使用动态规划计算出dp数组,最后输出最小成本和最小成本对应的路径。在输出路径时,我们使用了一个path数组来记录最短路径的情况,方便输出路径。
下面是完整的Python代码实现:
```python
import sys
n, m = map(int, input().split())
# 初始化cost数组
cost = [[float('inf')] * n for _ in range(n)]
for i in range(n):
cost[i][i] = 0
# 读入边
for i in range(m):
a, b, c = map(int, input().split())
cost[a][b] = c
# 动态规划
dp = [[float('inf')] * n for _ in range(1 << n)]
dp[1][0] = 0
path = [[0] * n for _ in range(1 << n)]
for i in range(1, 1 << n):
for j in range(n):
if i & (1 << j):
for k in range(n):
if i & (1 << k) and cost[k][j] != float('inf') and dp[i - (1 << j)][k] != float('inf'):
if dp[i][j] > dp[i - (1 << j)][k] + cost[k][j]:
dp[i][j] = dp[i - (1 << j)][k] + cost[k][j]
path[i][j] = k
# 输出结果
if dp[(1 << n) - 1][0] == float('inf'):
print(-1)
else:
print(dp[(1 << n) - 1][0])
p = (1 << n) - 1
res = [0]
while p > 0:
res.append(path[p][res[-1]])
p -= 1 << res[-1]
print(' -> '.join(map(str, res)))
```
以上就是本次实验的全部内容。通过本次实验,我们学习了旅行商问题的解法,了解了动态规划的思想和实现方法。