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

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

  • 题目描述:n个点的带权无向图,从0-n-1,求从起点0到终点n-1的最短Hamilton路径(Hamilton路径:从0-n-1不重不漏的每个点恰好进过一次)
  • 题解:二进制状态压缩算法\(O(2^n*n^2)\),需要记录当前经过了哪些点,当前在哪个位置。\(f[i][j]\) ? \(i\)转化为二进制每一位代表是否经过该点,\(j\)表示当前位于j这个点
#include <iostream>
#include <cstring>
using namespace std;

int f[1<<20][20];//0-19 location; status,loction
int w[20][20];
int main(){
    int n;scanf("%d",&n);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++) {
            scanf("%d", &w[i][j]);
        }
    }

    memset(f,0x3f,sizeof(f));
    f[1][0]=0;
    int im=1<<n;
    int ps;

    for(int i=1;i<im;i++)
        for(int j=0;j<n;j++)if((i>>j)&1)//the previous status is available
         {
            ps=i^(1<<j);//the previous status
            for (int k = 0; k < n;k++)if(ps&(1<<k))//find the previous available location
                f[i][j] = min(f[i][j], f[ps][k] + w[k][j]);
         }
    printf("%d",f[(1<<n)-1][n-1]);
    return 0;
}

原文地址:https://www.cnblogs.com/sstealer/p/11112392.html

时间: 2024-11-06 22:27:17

# 最短Hamilton路径(二进制状态压缩)的相关文章

『最短Hamilton路径 状态压缩DP』

状压DP入门 最短Hamilton路径 Description 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. Input Format 第一行一个整数n. 接下来n行每行n个整数,其中第i行第j个整数表示点i到j的距离(一个不超过10^7的正整数,记为a[i,j]). 对于任意的x,y,z,数据保证 a[x,x]=0,a[x,y]=a[y

最短Hamilton路径-状压dp解法

最短Hamilton路径 时间限制: 2 Sec  内存限制: 128 MB 题目描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. 输入 第一行一个整数n. 接下来n行每行n个整数,其中第i行第j个整数表示点i到j的距离(一个不超过10^7的正整数,记为a[i,j]). 对于任意的x,y,z,数据保证 a[x,x]=0,a[x,y]=a

二进制状态压缩及位运算

位运算符: 与(&),或(|),非(~), 异或(^); 移位运算: 1.左移:在二进制表示下把数字同时向左移动,低位以0填充,高位越界后舍弃 1 << n = 2^n, n << 1 = 2n 2.算术右移:在二进制补码表示下把数字同时向右移动,高位以符号位填充,低位越界后舍弃 n >> 1 = n/2.0(向下取整) eg:(-3)>> 1 = -2, 3 >> 1 = 1;  二进制状态压缩,是指将一个n位的 bool 数组用 n

完全图的最短Hamilton路径——状压dp

题意:给出一张含有n(n<20)个点的完全图,求从0号节点到第n-1号节点的最短Hamilton路径.Hamilton路径是指不重不漏地经过每一个点的路径. 算法进阶上的一道状压例题,复杂度为O(n^2 * 2^n),还是蛮恐怖的. 设f[i][j]表示当前经过状态为i,且当前在点j所花费的最小代价.其中i是二进制压缩值,从0-n-1位分别表示这个点是否经过了.目标状态为f[2^n - 1][n - 1],那么我们从小到大枚举i,再循环枚举当前点j和上一个状态所在的点k即可. 转移方程:f[i,

二进制状态压缩:应用及例题

1.位运算:https://www.cnblogs.com/yrjns/p/11246163.html 符号 描述 运算规则 & 与 两个位都为1时,结果才为1 | 或 两个位都为0时,结果才为0 ^ 异或 两个位相同为0,相异为1 ~ 取反 0变1,1变0 << 左移 各二进位全部左移若干位,高位丢弃,低位补0 >> 右移 各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移) Tips: (1)&a

最短Hamilton路径

题目描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. 输入 第一行一个整数n. 接下来n行每行n个整数,其中第i行第j个整数表示点i到j的距离(一个不超过10^7的正整数,记为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]. 输出 一个整数

Contest Hunter 0103 最短Hamilton路径 - 状压DP

传送门 思路: 1.状态:由于经过的点是一个集合,所以我们用dis[i][j]表示经过的点的状态为i,且当前位于点j时的最短Hamilton路径,其中i为一个二进制整数,用来存储经过的点的情况.为了方便位运算,我们的点的标号为0~n-1. 2.边界:dis[1][0]表示当前在起点0的最短Hamilton路径. 最终答案在dis[(1<<n)-1][n-1],即0~n-1所有点都被经过了一遍,当前在终点n-1的最短Hamilton路径. 3.决策:对于两点i,j,有两种决策:一是直接通过当前求

P1171 售货员的难题 - 状压DP【最短Hamilton路径】

P1171 售货员的难题 Sol: 最短Hamilton路径,经典的NPC问题,小数据可以通过状压DP 实现. 状态:\(f[i][j]\)表示当前在第i号点,且已经过的点的状态为j 时的最短Hamilton路径. 阶段:若以点为阶段,由于会从点i转移到点i+1,还可能从i+1转移到i-1,不具有无后效性,因此我们考虑以二进制状态为阶段进行转移. 决策:考虑由哪一个点转移而来. 转移:\(f[i][j]=\max \limits_{i\&(1<<i)\&\&i\&

位运算 - 最短Hamilton路径

给定一张 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路径