最短Hamilton路径(二进制状态压缩DP)

最短hamilton路径问题已经被证明是一个NPhard问题,求解最短路径复杂,所以要对问题进行状态压缩,我们用f[i][j]来表示以节点j为结尾时所经过的节点。表示方式为将第一维的i以二进制来进行表示,每一位的1或0表示该点是否被走过,所以我们第一维有2^{n}种状态。我们以8个节点为例,第一个节点为0,最后一个节点为7,我们所需要求的最终状态即为f[255][7]

将255转化为二进制表示即为011111111,可以发现该状态为从0到7所有节点都被遍历且以7为结尾,说明我们遍历了图中所有的节点一次并且来到了终点7。

ACcode

// #pragma GCC optimize (2)
// #pragma G++ optimize (2)
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define endl '\n'
#define int long long
#define lowbit(x) x &(-x)
#define rep(i, a, n) for (int i = a; i <= n; i++)
const double esp = 1e-5;
using namespace std;
void TLE() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); }
const int N=20,M=1<<20;
int f[M][N],weight[N][N];
int n;
void solve()
{
    cin>>n; 
    for(int i=0;i>weight[i][j];//保存图中信息
    memset(f,0x3f,sizeof(f));
    f[1][0]=0;//遍历过1号节点且以0为终点的路径个数为1
    for(int i=0;i<1<>j&1)//判断该状态是否合法经历过j并且以j为结尾才为合法状态,只需判断i的二进制表示第j个位置是否为1
                for(int k=0;k>k&1)//判断该更新是否合法
                    {
                       f[i][j]=min(f[i][j],f[i-(1<>T;
    while (T--)
        solve();
    return 0;
}

你可能感兴趣的:(比赛补题+记录,c++,蓝桥杯,拓扑学)