头歌05-排列树实验-旅行商问题

"""

题目:设有n个城市组成的交通图,一个售货员从住地城市q出发,到其它城市各一次去推销货物,最后回到住地城市。

要求:假定两个城市a,b 从a到b的路程花费w_ab是已知的,问应该怎样选择一条花费最少的路线?

输入格式:

第一行n m q,n和m两个整数分别表示城市数n以及城市之间的单向路数量m,q表示住地城市(出发城市)

之后m行 a b w分别表示从城市a到城市b的单向路程的花费w_ab。

输出格式:

第一行输出最小花费是D,D表示计算得到的最小花费。

第二行输出最小花费共有N种方案,分别是:,N表示最小花费方案的种类,

接下来N行输出每种方案的前往顺序,以字典序排序输出,中间以空格分隔。

输入样例:

3 6 A

A B 12

A C 4

B C 5

B A 8

C B 7

C A 2

输出样例:

最小花费是19

最小花费共有2种方案,分别是:

A B C

A C B

"""

复制代码
from itertools import permutations
import sys

def tsp(n, m, q, edges):
    # 将城市名称转换为索引
    city_to_index = {chr(ord('A') + i): i for i in range(n)}
    index_to_city = {i: chr(ord('A') + i) for i in range(n)}
    
    if q not in city_to_index:
        raise ValueError(f"住地城市 {q} 不存在于城市列表中。")
        
    q = city_to_index[q]

    # 初始化距离矩阵,INF 表示两城市间无直接路径
    INF = sys.maxsize
    dist = [[INF] * n for _ in range(n)]
    for i in range(n):
        dist[i][i] = 0

    for a, b, w in edges:
        if a not in city_to_index or b not in city_to_index:
            raise ValueError(f"城市 {a} 或 {b} 不存在于城市列表中。")
        dist[city_to_index[a]][city_to_index[b]] = w

    # 动态规划表
    dp = [[INF] * n for _ in range(1 << n)]
    dp[1 << q][q] = 0

    # 遍历所有状态
    for mask in range(1 << n):
        for i in range(n):
            if mask & (1 << i):
                for j in range(n):
                    if not mask & (1 << j):
                        dp[mask | (1 << j)][j] = min(
                            dp[mask | (1 << j)][j], dp[mask][i] + dist[i][j])

    # 寻找最小花费
    min_cost = INF
    for i in range(n):
        if i != q:
            min_cost = min(min_cost, dp[(1 << n) - 1][i] + dist[i][q])

    # 找到所有最小花费的路径
    def find_paths(mask, i):
        if mask == (1 << q):
            return [[index_to_city[i]]]

        paths = []
        for j in range(n):
            if mask & (1 << j) and dp[mask][i] == dp[mask ^ (1 << i)][j] + dist[j][i]:
                for path in find_paths(mask ^ (1 << i), j):
                    paths.append(path + [index_to_city[i]])
        return paths

    result_paths = []
    for i in range(n):
        if i != q and dp[(1 << n) - 1][i] + dist[i][q] == min_cost:
            for path in find_paths((1 << n) - 1, i):
                result_paths.append(path)

    result_paths = sorted(result_paths)
    return min_cost, result_paths


# 输入处理
n, m, q = input().split()
n = int(n)
m = int(m)

edges = []
for _ in range(m):
    a, b, w = input().split()
    w = int(w)
    edges.append((a, b, w))

min_cost, result_paths = tsp(n, m, q, edges)

# 输出结果
print(f"最小花费是{min_cost}")
print(f"最小花费共有{len(result_paths)}种方案,分别是:")
for path in result_paths:
    print(" ".join(path))
相关推荐
爬山算法2 分钟前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
智驱力人工智能4 分钟前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
qq_160144877 分钟前
亲测!2026年零基础学AI的入门干货,新手照做就能上手
人工智能
Howie Zphile8 分钟前
全面预算管理难以落地的核心真相:“完美模型幻觉”的认知误区
人工智能·全面预算
人工不智能57710 分钟前
拆解 BERT:Output 中的 Hidden States 到底藏了什么秘密?
人工智能·深度学习·bert
盟接之桥13 分钟前
盟接之桥说制造:引流品 × 利润品,全球电商平台高效产品组合策略(供讨论)
大数据·linux·服务器·网络·人工智能·制造
kfyty72513 分钟前
集成 spring-ai 2.x 实践中遇到的一些问题及解决方案
java·人工智能·spring-ai
猫头虎15 分钟前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven
李少兄16 分钟前
在 IntelliJ IDEA 中修改 Git 远程仓库地址
java·git·intellij-idea
h64648564h30 分钟前
CANN 性能剖析与调优全指南:从 Profiling 到 Kernel 级优化
人工智能·深度学习