最短Hamilton路径(0x01 位运算)

简介: 笔记

最短Hamilton路径


题意

给定一张 n 个点的带权无向图,点从 0∼n−1 标号,求起点 0 到终点 n−1 的最短 Hamilton 路径。


Hamilton 路径的定义是从 0 到 n−1 不重不漏地经过每个点恰好一次。


思路:

将每个点的状态用一个二进制整数 i 表示,i的第 k 位为 1 表示经过了第 k 个点,否则表示还没经过第 k 个点


然后用 j 表示当前状态下最后一个经过的点的编号,f[i][j] 表示 当前经过的点的状态为 i 最后一个经过的点为 j 的最短路径


那么我们要求的就是 f[(1 << n) - 1][n - 1] 即点 0~n-1 都经过,且最后经过的点为 n-1 的最短路径


因为每一个点只能被经过一次,那么j 一定是刚刚经过的,所以上一步的状态是 i ^ (1 << j) 即 i的第 j 位为 0 。另外,上一时刻所在的点可能是 i ^ (1 << j) 中任何一个为1 的点 k 所以可以考虑


所有满足((i ^ (1 << j) >> k) & 1 的点,求 f[((i ^ (1 << j) >> k) & 1][k] + w[k][j] 的最小值即可


代码

#include<bits/stdc++.h>
// #define int long long
#define INF 0x3f3f3f3f
#define mod 1000000007
#define rep(i, st, ed) for (int (i) = (st); (i) <= (ed);++(i))
#define pre(i, ed, st) for (int (i) = (ed); (i) >= (st);--(i))
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
template<typename T> inline T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<typename T> inline T lowbit(T x) { return x & -x; }
const int N = 1e5 + 10;
int n;
int f[1 << 20][20]; // i - 当前状态 j - 最后经过的点为j点
int w[20][20];
void solve() {
  cin >> n;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      cin >> w[i][j];
    }
  }
  memset(f, 0x3f, sizeof f);
  f[1][0] = 0;
  for (int i = 0; i < (1 << 20); ++i) { // 当前路径的状态 1表示经过 0表示未经过
    for (int j = 0; j < n; ++j) { // 当前走到了哪个点
      if ((i >> j) & 1) {
        for (int k = 0; k < n; ++k) { // 上一步走到了哪个点
          if ((i ^ (1 << j)) & (1 << k)) {
            f[i][j] = min(f[i][j], f[i ^ (1 << j)][k] + w[k][j]);
          }
        }
      }
    }
  }
  cout << f[(1 << n) - 1][n - 1] << endl;
}
signed main() {
  // int t; cin >> t;
  // while (t--)
    solve();
  return 0;
}


目录
相关文章
|
7月前
|
算法 测试技术 C++
【动态规划】【字符串】1092. 最短公共超序列
【动态规划】【字符串】1092. 最短公共超序列
|
7月前
|
关系型数据库 测试技术 RDS
【动态规划】【字符串】【状态压缩】943 最短超级串
【动态规划】【字符串】【状态压缩】943 最短超级串
|
算法 测试技术 C++
C++算法:最短回文串
C++算法:最短回文串
|
7月前
leetcode-329:矩阵中的最长递增路径
leetcode-329:矩阵中的最长递增路径
58 0
|
2月前
|
JavaScript
AcWing 91. 最短Hamilton路径
AcWing 91. 最短Hamilton路径
19 0
【Leetcode -748.最短补全词 -762.二进制表示中质数个计算置位】
【Leetcode -748.最短补全词 -762.二进制表示中质数个计算置位】
54 0
|
7月前
|
Python C++ Java
C/C++每日一练(20230415) 交错字符串、最短回文串、分段函数
C/C++每日一练(20230415) 交错字符串、最短回文串、分段函数
56 0
C/C++每日一练(20230415) 交错字符串、最短回文串、分段函数
|
7月前
|
Python Java Go
Python每日一练(20230428) 最长有效括号、矩阵最长递增路径、回文链表
Python每日一练(20230428) 最长有效括号、矩阵最长递增路径、回文链表
65 0
Python每日一练(20230428) 最长有效括号、矩阵最长递增路径、回文链表
|
7月前
代码随想录 Day44 动规12 LeetCode T300 最长递增子序列 T674 最长连续递增序列 T718 最长重复子数组
代码随想录 Day44 动规12 LeetCode T300 最长递增子序列 T674 最长连续递增序列 T718 最长重复子数组
68 0
|
7月前
|
存储 算法 Java
给定一个二叉树,请你找出其中最长严格递增路径的长度。(提示:使用动态规划)
给定一个二叉树,请你找出其中最长严格递增路径的长度。(提示:使用动态规划)
57 0