首页 > 其他分享 >【状压DP】哈密顿回路问题

【状压DP】哈密顿回路问题

时间:2022-11-25 20:02:08浏览次数:63  
标签:路径 哈密顿 int 状压 回路 集合 DP


【状压DP】哈密顿回路问题

lzq同学在我准备午睡的时候发了一道蓝桥杯的题目给我,是哈密顿回路的。第一次看的时候是想DFS+双向搜索优化减小搜索树规模,然后写烂了(如果有大佬用搜索优化写出来了麻烦教教我这蒟蒻)。
后来请教了ph大佬,说是状压dp。确实,以前蓝书上见到过一道最短哈密顿路径的状压DP,所以学了点相关知识

哈密顿图定义

哈密顿图
通过图中所有顶点一次且仅一次的通路称为哈密顿通路。
通过图中所有顶点一次且仅一次的回路称为哈密顿回路。
具有哈密顿回路的图称为哈密顿图。
具有哈密顿通路而不具有哈密顿回路的图称为半哈密顿图。

最短Hamilton路径

思路

暴力搞的话复杂度为【状压DP】哈密顿回路问题_i++显然的NP难题,直接暴力很难搞

状态表示

f(i,j)

集合:所有从0走到j,走过的所有点是i的所有路径

属性:Min

状态计算

枚举倒数第二个点是哪个点,用倒数第二个点来分类

【状压DP】哈密顿回路问题_哈密顿回路_02


【状压DP】哈密顿回路问题_状压dp_03


【状压DP】哈密顿回路问题_i++_04

i的意义是一个集合,将这个集合转化为一个数,然后用位移运算来实现操作。

目标【状压DP】哈密顿回路问题_i++_05

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=20,M=1<<N;
LL g[N][N],f[M][N];
int n;
int main()
{
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>g[i][j];

memset(f,0x3f,sizeof f);

f[1][0]=0;
for(int i=0;i<(1<<n);i++)//集合状态
for(int j=0;j<n;j++)
if(i>>j&1)//看j点有没有到
for(int k=0;k<n;k++)//枚举倒数第二个点
if(((i-(1<<j))>>k)&1)//i集合出去j点后k点也要存在
f[i][j]=min(f[i][j],f[i-(1<<j)][k]+g[k][j]);//状态计算最小值
cout<<f[(1<<n)-1][n-1]<<endl;

return 0;
}

蓝桥杯 E:回路计数

【状压DP】哈密顿回路问题_哈密顿回路_06

代码

状态表示

【状压DP】哈密顿回路问题_状压dp_07

集合:所有从1走到j,走过的所有点是i的所有路径

属性:方案数

状态转移:【状压DP】哈密顿回路问题_状压dp_08

目标:【状压DP】哈密顿回路问题_i++_09

初始化:20个起点为1

【状压DP】哈密顿回路问题_哈密顿回路_10

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=20,M=1<<N;
LL st[N][N];
LL f[M][N];
int n;
int main()
{
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
if(__gcd(i+2,j+2)==1)st[i][j]=1;

for(int i=0;i<N;i++)f[1<<i][i]=1;//点集里只有自己,此时作为起点

for(int i=0;i<(1<<N);i++)//集合状态
for(int j=0;j<N;j++)
if(i>>j&1)//看j点有没有到
for(int k=0;k<N;k++)//枚举倒数第二个点
if(((i-(1<<j))>>k)&1)//i集合除去j点后k点也要存在
if(st[k][j])f[i][j]+=f[i-(1<<j)][k];//状态计算
LL ans=0;
for(int i=0;i<N;i++)ans+=f[(1<<N)-1][i];//(1<<N)-1一定要加括号!
cout<<ans<<endl;

return 0;
}

CodeForces 11D A Simple Task (待补)

​https://codeforces.com/problemset/problem/11/D​

【状压DP】哈密顿回路问题_状压dp_11

思路

题目越短,难度越大hh
这道题就是求长度>=3的哈密顿路径数。
哈密顿回路状压DP计数,这题应该是蓝桥杯的原题了吧hh,远古题目对标当时CF2200分。哇,我怎么敢的呀。
​参考博客​​中学生吊锤大学生系列

由于去重比较恶心,所以这题暂时放一下,但是那个博客真滴很牛逼,强烈推荐看一看

代码

在这里插入代码片

小结

状态方程

表示含义

f(i,j)

从起点,路径经过节点状态集合为i,到目标点j

f(1<<i,i)

从0开始,路径上只有起点i

f(1<<(i-1),i)

从1开始,路径上只有起点i

f(i-(1<<j),k)

从0开始到k点,路径还没经过j

f(1<<S-1,j)

S表示总节点数,从起点0走到终点j,走完所有节点

if(i>>j&1)

看有没有走到j

if(((i-(1<<j))>>k)&1)

集合i除去节点j后是经过k的

区分起点0和1
起点初始化
走过所有集合的状态表示


标签:路径,哈密顿,int,状压,回路,集合,DP
From: https://blog.51cto.com/u_15891800/5887710

相关文章

  • [DP 字符串 计数去重]L3-020 至多删三个字符
    [DP字符串]L3-020至多删三个字符题目思路状态表示集合属性:count(不包含重复)状态计算:删除第i个或者不删除第i个这题比较恶心的地方在于去重aacdbb删掉最后一个b和删除......
  • [DP 形状 线性]P1990 覆盖墙壁
    [DP形状线性]P1990覆盖墙壁​​题目链接​​思路把边界形状作为状态标识,类似杨老师照相序列那题为长度为i,状态为j的方案数目标是:代码//Problem:P1990覆盖墙壁//Con......
  • [DP 01背包/差值DP 存在性]小M和天平
    [DP01背包/差值DP存在性]小M和天平题目室友大佬去玩了蓝桥杯,听室友回寝口述的题目,然后水群的时候群友说和这题差不多就做一下。感觉和不久前做的差值DP有点关系。思路两种......
  • DOS批处理中%cd%和%~dp0的区别
    %cd%和%~dp0的区别 在DOS的批处理中,有时候需要知道当前的路径。%cd%,一个是%~dp0。   这两个变量的用法和代表的内容是不同的。  %cd% ......
  • [dp 记录]P3349 [ZJOI2016]小星星
    绝世容斥好题,刚好NOIp前要复习容斥,就拉过来当100紫了。祝自己明天的NOIprp++这题好久前看过题解,感觉好可惜,浪费了好题。以后自己不会的题也不能看题解了。题意:......
  • WordPress编辑器支持Word自动上传
    ​ 1.4.2之后官方并没有做功能的改动,1.4.2在word复制这块没有bug,其他版本会出现手动无法转存的情况本文使用的后台是Java。前端为Jsp(前端都一样,后台如果语言不通得自己......
  • 【iOS开发必备指南合集】申请企业级IDP、真机调试、游戏接入GameCenter 指南(实现仿官
    ​​ 李华明Himi ​​​原创,转载务必在明显处注明    这里Himi给出对于开发iOS的朋友们整理一个指南集合,其中主要包括申请IDP需要注意的地方、有了开发者证书如......
  • WordPress编辑器支持Word图片粘贴
    ​ 百度ueditor新增的将word内容导入到富文本编辑框的功能怎么没有啊,...ueditor实现word文档的导入和下载功能的方法:1、UEditor没有提供word的导入功能,只能说是粘贴复......
  • WordPress编辑器支持Word图片上传
    ​ 当前功能基于PHP,其它语言流程大抵相同。大概流程:1.将docx文件上传到服务器中2.使用PHPoffice/PHPword实现将word转换为HTML3.将HTML代码返回并赋值到编辑器中......
  • WordPress编辑器支持Word图片导入
    ​当前功能基于PHP,其它语言流程大致相同 1.新增上传wordjson配置在ueditor\php\config.json中新增如下配置:     /* 上传word配置 */    "wordActionNa......