最短Hamilton路径(状压dp)
最短Hamilton路径实际上就是状压dp,而且这是一道作为一个初学状压dp的我应该必做的题目
题目描述
给定一张 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]。
输出
一个整数,表示最短Hamilton路径的长度。
样例数据
4
0 2 1 3
2 0 2 1
1 2 0 1
3 1 1 0
思路讲解
作为一道最基础的状压dp ,我们需要掌握它为什么是这么做的。
我作为一名菜鸡,首先想到的就是朴素做法,可是朴素做法它的时间复杂度不允许我通过这道题目。
那我们分析一下朴素做法,从起点到终点每个点只经过一次且求最短路径,,,嗯,最暴力的话就是我们应该把所有的不同种路径全都枚举出来(这个当然就是全排列啦),然后去比较寻找最短路径。
那么这个复杂度是O(n*n !),因为我们枚举所有情况是O(n!),然后每一种路径求和是O(n)的,所以总复杂度是O(n*n!),这个不难分析。
但是我们想了,这么大的复杂度该怎么办呢? 我们再来想想 ,我们的复杂度之所以大是因为 “ n! ” ,所以我们试图从这里想想办法。
枚举每一位,所有种方案,,,我们可以用二进制,因为二进制同样可以把一组数表示出来,,所以我们想到了用状压去做。
我们定义f(i,j) i 表示的是当前的二进制数 , j 表示的是当前所到达的二进制的第j位
在任意时刻,我们还需要知道当前所处的位置,因此我们用f(i ,j )表示“点被经过的状态” 对应的二进制数位i 且目前处于j时的最短路径。
在任意时刻,有公式f【i,j】=min(i xor (1<<j) , k )+a(k,j) a数组表示从k到j的路径大小。
i xor (1<<j ) 表示的是在上一时刻我们所处位置是的路径和
所以公式的意思就明白了 ,就是上一个时刻的路径和与当前时刻的路径和大小的比较
代码实现
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; int n ;
int a[25][25]; // 代表i到j路径花费
int f[1<<22][25]; //利用二进制的思想 , i表示的是当前的二进制数, j表示的是当前所到达的二进制的第j位
int main(){
scanf("%d",&n);
for(int i=0 ;i<n;i++){
for(int j=0 ;j<n;j++){
scanf("%d",&a[i][j]);
}
} memset(f,127,sizeof(f));
f[1][0] = 0 ;
for(int i=1 ;i<(1<<n);i++){
for(int j=0 ; j<n ;j++){
if((i>>j)&1){ //表示的是我们枚举二进制数的时候 ,这个数中第j位是不是已经被选中了,如果没选过,那我们还用它干嘛。最后的结果不就是n-1个数全部选中嘛
for(int k=0 ;k<n ;k++ ){
if((i>>k)&1){
f[i][j] = min(f[i][j], f[i^(1<<j)][k]+a[k][j]) ;
}
}
}
}
}
cout << f[(1<<n)-1][n-1]<<endl;
return 0 ;
}
最短Hamilton路径(状压dp)的更多相关文章
- 完全图的最短Hamilton路径——状压dp
题意:给出一张含有n(n<20)个点的完全图,求从0号节点到第n-1号节点的最短Hamilton路径.Hamilton路径是指不重不漏地经过每一个点的路径. 算法进阶上的一道状压例题,复杂度为O ...
- 最短Hamilton路径-状压dp解法
最短Hamilton路径 时间限制: 2 Sec 内存限制: 128 MB 题目描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamil ...
- Acwing-91-最短Hamilton路径(状压DP)
链接: https://www.acwing.com/problem/content/93/ 题意: 给定一张 n 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hami ...
- 『最短Hamilton路径 状态压缩DP』
状压DP入门 最短Hamilton路径 Description 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamil ...
- CH0103最短Hamilton路径 & poj2288 Islands and Brigdes【状压DP】
虐狗宝典学习笔记: 取出整数\(n\)在二进制表示下的第\(k\)位 \((n >> ...
- 最短Hamilton路径【状压DP】
给定一张 nn 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. 输入 ...
- 0103 最短Hamilton路径【状压DP】
0103 最短Hamilton路径 0x00「基本算法」例题 描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Ham ...
- AcWing 最短Hamilton距离 (状压DP)
题目描述 给定一张 n 个点的带权无向图,点从 0∼n−1 标号,求起点 0 到终点 n−1 的最短 Hamilton 路径. Hamilton 路径的定义是从 0 到 n−1 不重不漏地经过每个点恰 ...
- 【状压dp】Hamiton路径
描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点 ...
随机推荐
- NOIP初赛篇——02计算机系统的基本结构
引言 计算机系统由硬件和软件两部分组成,硬件系统是计算机的"躯干",是物质基础.而软件系统则是建立在这个"躯干"上的"灵魂". 计算机硬件 ...
- Spring Boot 2.0 的配置绑定类Bindable居然如此强大
1. 前言 在开发Spring Boot应用时会用到根据条件来向Spring IoC容器注入Bean.比如配置文件存在了某个配置属性才注入Bean : 图中红色的部分是说,只有ali.pay.v1.a ...
- fastjson反序列化漏洞原理及利用
重要漏洞利用poc及版本 我是从github上的参考中直接copy的exp,这个类就是要注入的类 import java.lang.Runtime; import java.lang.Process; ...
- Python Kafka Client 性能测试
一.前言 由于工作原因使用到了 Kafka,而现有的代码并不能满足性能需求,所以需要开发高效读写 Kafka 的工具,本文是一个 Python Kafka Client 的性能测试记录,通过本次测试, ...
- MongoDB备份(mongodump)与恢复(mongorestore)工具实践
mongodump和mongorestore实践 1.mongodump备份工具 mongodump能够在Mongodb运行时进行备份,它的工作原理是对运行的Mongodb做查询,然后将所有查到的文档 ...
- Mac pycharm更换版本后打不开
1.第一步:先输入: cd /Applications/PyCharm.app/Contents/MacOS 2.第二步:查看无法打开pycharm的原因,需要输入:c./pycharm 3.第三 ...
- [CPP] 智能指针
介绍 C++ 的智能指针 (Smart Pointers) 相关 API. C++ 中的智能指针是为了解决内存泄漏.重复释放等问题而提出的,它基于 RAII (Resource Acquisition ...
- 【Oracle】查看某个角色中有什么权限
select * from role_sys_privs where role='DBA'; 查看dba都有什么系统权限 select * from role_sys_privs where rol ...
- OpenID协议
背景 当我们要使用一个网站的功能时,一般都需要注册想用的账号.现在的互联网应用很多,一段时间之后你会发现你注册了一堆账号密码,根本记不住. 你可能会想到所有的网站都用同一套用户名和密码,这样虽然能解决 ...
- SSTI
最牛bypass:https://blog.csdn.net/solitudi/article/details/107752717 SSTI的奇怪绕过姿势:https://blog.csdn.net/ ...