题目链接:点击查看

题目大意:求从0开始的最短哈密顿路径,并且要求了某些点的先后顺序

题目分析:哈密顿路径:由指定的起点前往指定的终点,途中经过所有其他节点且只经过一次(百度百科)

既然按照一定的次序求最短路,可以模仿floyd求最短路的思想,然后套用状态压缩的模板来做,在状态压缩的过程中,1表示该点已经走过,0表示该点还未走过,dp[i][j]代表状态i到终点j的最短距离,那么初始化就是dp[1][0]=0,其余都为inf


2019.11.28更新:

看了大蓝书后学了一种新的方法实现哈密顿路径,比之前这个代码更好理解更好实现了,特地来更新一下

直接上代码吧,注释比较清晰,有一点需要注意,可能是数据比较水的原因,用memset会MLE,但用for循环稳过

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<sstream>
using namespace std;const int inf=0x3f3f3f3f;const int N=(1<<21)+100;int dp[N][25];//dp[i][j]代表状态i到终点j的最短距离,状态:1表示已经走过该点,0表示未走过 int f[25];int d[25][25];int main()
{
//  freopen("input.txt","r",stdin);int n,m;while(scanf("%d%d",&n,&m)!=EOF){for(int i=0;i<(1<<n);i++)for(int j=0;j<n;j++)dp[i][j]=inf;for(int i=0;i<n;i++)f[i]=0;dp[1][0]=0;//初始化 for(int i=0;i<n;i++){for(int j=0;j<n;j++){scanf("%d",&d[i][j]);}}while(m--){int u,v;scanf("%d%d",&u,&v);f[v]|=(1<<u);}for(int i=0;i<(1<<n);i++){for(int j=0;j<n;j++){if(dp[i][j]==inf)continue;for(int k=0;k<n;k++){if(d[j][k]==-1)continue;if(!(i&(1<<j)))//没走过j点,故不能用j点当中间点连接continue;if((i&(1<<k)))//已经走过k点,根据哈密顿路径的性质不能重复经过某个顶点continue;if((f[k]&i)!=f[k])//还未满足先行条件continue;dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+d[j][k]);//状态转移方程}}}int ans=inf;for(int i=0;i<n;i++)ans=min(ans,dp[(1<<n)-1][i]);if(ans==inf)cout<<-1<<endl;elsecout<<ans<<endl;}return 0;
}

更新:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=22;int maze[N][N],f[N];int d[1<<N][N];int main()
{
//  freopen("input.txt","r",stdin);
//    ios::sync_with_stdio(false);int n,m;while(scanf("%d%d",&n,&m)!=EOF){for(int i=0;i<n;i++)for(int j=0;j<n;j++){scanf("%d",&maze[i][j]);if(maze[i][j]==-1)maze[i][j]=inf;}for(int i=0;i<1<<n;i++)for(int j=0;j<n;j++)d[i][j]=inf;for(int i=0;i<n;i++)f[i]=0;d[1][0]=0;while(m--){int u,v;scanf("%d%d",&u,&v);f[v]|=(1<<u);}for(int i=1;i<1<<n;i++)//枚举状态 {for(int j=0;j<n;j++)//枚举终点 {if((f[j]&i)!=f[j])//若终点的前置点都没有满足,直接剪枝 continue;if(i>>j&1){for(int k=0;k<n;k++)//枚举起点{d[i][j]=min(d[i][j],d[i^1<<j][k]+maze[k][j]);} }} }int ans=inf;for(int i=0;i<n;i++)ans=min(ans,d[(1<<n)-1][i]);if(ans==inf)printf("-1\n");elseprintf("%d\n",ans);}return 0;
}

HDU - 3538 A sample Hamilton path(最短哈密顿路径+状压dp)相关推荐

  1. 牛客 - 收集纸片(最短哈密顿路径-状压dp)

    题目链接:点击查看 题目大意:给出一个 n * m 的二维平面,其中有 k 个纸片,给出第一个纸片的位置,要求从第一个纸片出发,经过每个纸片一次后再回到第一个纸片的位置,输出最短路径 题目分析:最短哈 ...

  2. [状压dp] 最短Hamilton路径(模板题+状压dp)

    文章目录 0. 前言 1. 状压dp 模板题 0. 前言 状压 dp 就是采用二进制数保存状态,方便进行位运算操作.例如 八皇后.八数码问题也都是采用了状态压缩的思想来使用一个二进制数唯一对应集合中的 ...

  3. hdu 6149 Valley Numer II(01背包套状压dp)

    题目链接:hdu 6149 Valley Numer II 题意: 给你N个点,有k个为高点,其他为低点,现在这N个点有m条边,问你最多能组成多少个两个高点一个低点,低点和两个高点都有边相连这样的状态 ...

  4. Codeforces 1741G 最短路上状压dp

    题意: 有 n n n个地方,他们被 m m m条道路相连.有一天, t o t tot tot个人在 1 1 1处开派对,开完派对他们要回家,他们回家只会走最短路径,其中有 k ( k ≤ 6 ) ...

  5. HDU - 4856 Tunnels(哈密顿路径+状压dp)

    题目链接:点击查看 题目大意:给出一个n*n的正方形网格,其中"."表示可以走的路,"#"表示障碍物,每次可以向上下左右任意方向走1格,花费1单位时间,再给出m ...

  6. CodeForces - 1102F Elongated Matrix(哈密顿路径+状压dp)

    题目链接:点击查看 题目大意:给出一个 n∗mn * mn∗m 的数字矩阵,现在可以对 行 进行重新排列,现在对排列后的矩阵按列展开成线性:s1,s2,-,snm=maze1,1,maze2,1,.. ...

  7. 刷题周记(九)——#状压DP:最短Hamilton路径、小国王(互不侵犯)、玉米田(Corn Fields G)、愤怒的小鸟、吃奶酪、炮兵阵地、宝藏 #区间DP:清空字符串#DP:关灯问题II

    文章目录 --2020年12月20日(周日)------------------ 状压DP 一.最短Hamilton路径(模板题) 二.玉米田(P1879 [USACO06NOV]Corn Field ...

  8. CH0103最短Hamilton路径 poj2288 Islands and Brigdes【状压DP】

    虐狗宝典学习笔记: 取出整数\(n\)在二进制表示下的第\(k\)位                                                    \((n >> ...

  9. 最短Hamilton路径(状压dp)

    链接:https://ac.nowcoder.com/acm/problem/50909 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...

最新文章

  1. 大数据安全标准现状和思考
  2. 史上最快! 10小时大数据入门实战(五)-分布式计算框架MapReduce
  3. Andoird --- 安卓 failed to connect to /192.168.0.135 (port 8080) after 1000ms
  4. Mybatis学习第一天——Mybatis的安装配置以及基本CURD操作
  5. linux隔行打印文本,详解正则表达式及Linux三大文本处理工具
  6. 技术动态 | 事理图谱,下一代知识图谱
  7. 远程登录服务器哪个工具好,远程登录服务器,有什么比较好用的工具?
  8. inner join ,left join ,right join 以及java时间转换
  9. 用 Node.js 把玩一番 Alfred Workflow
  10. java 136年以后的时间_136年清明查询 - 136年清明是几号 - 136年清明具体时间
  11. floyd算法_常用十大算法(九)— 弗洛伊德算法
  12. 如何读计算机领域的论文,计算机领域学术论文分类
  13. 机器学习时代三大神器GBDT(MART)、XGBoost、LightGBM
  14. 计算机毕业设计Python+uniapp校园服务微信小程序(小程序+源码+LW)
  15. 线程1(Thread)
  16. aws没有免费套餐服务数据可用
  17. python pydicom读取dicom文件信息的几种方式
  18. 如何用计算机拍照,怎样用电脑照相
  19. liunx系统文本处理命令
  20. 如何使用NC进行通信

热门文章

  1. Lua语法入门HelloWorld
  2. Redis中的Lua 脚本
  3. MyBatis常用配置解析-environments标签
  4. 搭建elasticsearch测试工程
  5. 实现runable接口创建线程
  6. 消息队列入门案例-编码
  7. Tomcat集群快速入门
  8. 深入理解Kafka(2)-Producer
  9. matlabk大于等于0如何表示_【底层原理】浮点数在计算机中是如何表示
  10. 一个完整网站的代码_网站优化三步走,怎样给自己的网站做优化?