欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

二进制状态压缩解决哈密顿最短路径问题

程序员文章站 2022-05-18 10:25:08
...

右边为第0位,左边为第n-1位

 1. 取出整数n在二进制表示下的第k位	(n>>k)&1
 1001 0100  取出第40000 1001&0000 0001-> 0000 0001
 2. 取出整数n在二进制表示下的第0~k-1位(后k位)  n&((1<<k)-1)
 1001 0100 取出后50010 0000-1=0001 1111 
 3.把整数n在二进制表示下的第k位取反
 n xor (1<<k)  异或运算
 4.把整数n在二进制表示下的第k位赋值1
 n|(1<<k)
 5.把整数n在二进制表示下的第k位赋值1
 n&(~(1<<k))  ~为取反操作

二进制状态压缩解决哈密顿最短路径问题

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int weight[20][20];//存边
int f[1<<20][20];
int main()
{
    int n;//n个顶点,编号为0-n-1
    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;//i=1,表示目前只经过了i点,j=0,表示目前在0号节点
    for(int i=1;i<1<<n;i++)//枚举所有的状态
    {
        for(int j=0;j<n;j++)//接下来是两层for循环,第一层枚举哪个顶点已经经过了,第二层循环
        {
            if(i>>j&1)//i的第j位是1,刚刚经过j
            {
                for(int k=0;k<n;k++)//枚举是哪个顶点到达j的
                {
                    if((i^1<<j)>>k&1)//i的第j位先弄为0,然后看哪个位是1,即有可能从该顶点到达顶点j
                        f[i][j]=min(f[i][j],f[i^1<<j][k]+weight[k][j]);
                }
            }
        }
    }
    cout<<f[(1<<n)-1][n-1];//终点是n-1,且前n-1个顶点都经过了
    return 0;
}

相关标签: 基本算法 算法