位运算之算法三—最短Hamilton路径

核心思路:
1 找到当前状态,即当前被用过的点。
2 当前所处的位置。

用一个二维数组保存f[state][j];
state 就是当前状态,通过二进制状态压缩进行表示,例如有二十组,用1<<20-1;表示状态已满。
j 就是当前点的位置。

通过每次判断当前位置是否遍历用state>>j&1;
然后再判断上一次的经过的点,寻找最小值,最后f[1<<20-1][20-1]就是所求的答案。

代码:

#include
#include
#include

using std::cin;
using std::cout;
using std::endl;
using std::min;

const int M=1<<20,N=20;
int f[M][N];//表示当前点的最小值
int weight[N][N];//存储权值

int main(void)
{
int n;
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>weight[i][j];
memset(f,0x3f,sizeof(f));//初始化最大值
f[1][0]=0;//第一个数路径为零
for(int i=1;i<1<<n;i++)
for(int j=0;j<n;j++)
if(i>>j&1)//判断 是否经过当前点
for(int k=0;k<n;k++)
if((i^1<<j)>>k&1)//判断经历的前一个点,状态为1都可以参与计算
f[i][j]=min(f[i][j],f[i^1<<j][k]+weight[k][j]);//求最小值
cout<<f[(1<<n)-1][n-1]<<endl;
return 0;
}

补充一下小知识:
lowbit 运算

求一个数的二进制的最后一个数值为一所在的位置。
eg:x=10010010;
对其求反~x=01101101;
再加一 ~x+1=01101110;
最后 result=x&(~x+1)=00000010;
log2(result)即为结果。

lowbit运算就是result=x&(~x+1);
在计算机中~x+1=-x;
即lowbit=x&-x;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值