最短Hamilton路径 状态压缩dp 旅行商问题(TSP)

本文介绍了使用状态压缩动态规划解决旅行商问题(TSP)的方法,通过位运算表示点的集合,并详细阐述了如何枚举所有走过的点,最后给出了相关代码实现。
摘要由CSDN通过智能技术生成
问题描述
给定一张 n 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短
Hamilton路径。 Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次。


输入格式:

第一行输入整数n。

接下来n行每行n个整数,其中第i行第j个整数表示点i到j的距离(记为a[i,j])。

对于任意的x,y,z,数据保证 a[x,x]=0,a[x,y]=a[y,x] 并且 a[x,y]+a[y,z]>=a[x,z]。

输出格式
输出一个整数,表示最短Hamilton路径的长度。

数据范围
1≤n≤201≤n≤20
0≤a[i,j]≤1070≤a[i,j]≤107
输入样例:
5
0 2 4 5 1
2 0 6 5 3
4 6 0 8 3
5 5 8 0 5
1	3 3 5 0
输出样例:
18
思路:
首先如果是暴力解的话复杂度大约是20! (2.4*10^18)根本不可能实现
然后我们降低复杂度,这个题我用的算法是状态压缩dp,
用f[i][j]表示当前已经走过点的集合为i,移动到j。所以这个状态转移方程就是找一个
中间点k,将已经走过点的集合i中去除掉j(表示j不在经过的点的集合中),然后再加上
从k到j的权值
状态转移方程:f[i][j] =  min( f[i][k] + 从k到j的距离 , f[i][j] )   K是 i去掉j之后 的子集 
怎么表示集合? 用位运算表示
假设给定20个元素,我们用二进制中0来表示元素未被选定,用1表示选定
例如:20个元素的子集有2^20个左右,我们用一个20位的二进制数来表示该集合
第i位的 0 与 1 表示第 i 个元素是否被选定,
假设已经走过1,,3,4这几个点,那么i就是 11010
那么怎么枚举所有走过的点的集合
对于任意i,判断( i >> x & 1 )的值是否为1 来确定第x位是1还是0 进而确地第x的点是否被走过
代码如下,还是看代码吧
#include<iostream>
#include<cmath>
#include<string.h>
#include<algorithm>
#include<string>
#include<cstdio>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值