『最短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,x] 并且 a[x,y]+a[y,z]>=a[x,z]。
Output Format
一个整数,表示最短Hamilton路径的长度。
Sample Input
4
0 2 1 3
2 0 2 1
1 2 0 1
3 1 1 0
Sample Output
4
解析
很容易想到的朴素解法是枚举全排列,时间复杂度\(O(n*!n)\),显然是会\(TLE\)的。注意到\(n<20\),我们考虑状态压缩\(DP\)。设\(f[i][S]\)代表当前遍历状态为\(S\),到了第\(i\)个点的最短长度。如何理解遍历状态\(S\)呢?我们把它当做一个二进制的\(01\)串,从右数第i位为如果为\(0\),就说明节点i没有被遍历到过,如果第\(i\)位为\(1\),则说明节点i被遍历到过了。我们将整个图的遍历状态记为一个二进制数,这就是状态压缩。
那么我们考虑如何\(DP\)。我们将编号记为从\(1\)开始的,那么初始状态就是\(f[1][1]=0\)。
这里我们需要先理解状态的查询和赋值操作:
1.
S&(1<<(i-1))
代表取出状态S的(从右往左)第i位
2.S|(1<<(i-1))
代表将状态S的(从右往左)第i位赋值为1
那么我们就可以得到状态转移方程了:$$f[j][S|(1<<(j-1))]=\min{f[i][S]+dis[i][j]}$$
需要满足节点\(j\)未访问,节点\(i\)已经访问过了。
状态的初值一开始均为正无穷,枚举\(S,i,j\)即可转移,时间复杂度\(O(n^2*2^n)\),目标状态为\(f[n][(1<<n)-1]\)。
\(Code:\)
#include<bits/stdc++.h>
using namespace std;
const int N=20;
int n,dis[N+5][N+5],f[N+5][(1<<N)+5],ans=0x3f3f3f3f;
inline void input(void)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&dis[i][j]);
}
inline void dp(void)
{
memset(f,0x3f,sizeof f);
f[1][1]=0;
for(int S=1;S<(1<<n);S++)
for(int i=1;i<=n;i++)
if(S&(1<<(i-1)))
for(int j=1;j<=n;j++)
if( not (S&(1<<(j-1))) )
f[j][S|(1<<(j-1))]=min(f[j][S|(1<<(j-1))],f[i][S]+dis[i][j]);
}
int main(void)
{
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
input();
dp();
printf("%d\n",f[n][(1<<n)-1]);
}
<后记>
『最短Hamilton路径 状态压缩DP』的更多相关文章
- 最短Hamilton路径-状压dp解法
最短Hamilton路径 时间限制: 2 Sec 内存限制: 128 MB 题目描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamil ...
- 完全图的最短Hamilton路径——状压dp
题意:给出一张含有n(n<20)个点的完全图,求从0号节点到第n-1号节点的最短Hamilton路径.Hamilton路径是指不重不漏地经过每一个点的路径. 算法进阶上的一道状压例题,复杂度为O ...
- # 最短Hamilton路径(二进制状态压缩)
最短Hamilton路径(二进制状态压缩) 题目描述:n个点的带权无向图,从0-n-1,求从起点0到终点n-1的最短Hamilton路径(Hamilton路径:从0-n-1不重不漏的每个点恰好进过一次 ...
- 最短Hamilton路径【状压DP】
给定一张 nn 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. 输入 ...
- 最短Hamilton路径(状压dp)
最短Hamilton路径实际上就是状压dp,而且这是一道作为一个初学状压dp的我应该必做的题目 题目描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 ...
- Light OJ 1406 Assassin`s Creed 状态压缩DP+强连通缩点+最小路径覆盖
题目来源:Light OJ 1406 Assassin`s Creed 题意:有向图 派出最少的人经过全部的城市 而且每一个人不能走别人走过的地方 思路:最少的的人能够走全然图 明显是最小路径覆盖问题 ...
- 最短Hamilton路径 数位dp
最短Hamilton路径 #include<bits/stdc++.h> using namespace std; ; <<maxn][maxn]; int maps[maxn ...
- 0103 最短Hamilton路径【状压DP】
0103 最短Hamilton路径 0x00「基本算法」例题 描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Ham ...
- POJ 3311 Hie with the Pie(Floyd+状态压缩DP)
题是看了这位的博客之后理解的,只不过我是又加了点简单的注释. 链接:http://blog.csdn.net/chinaczy/article/details/5890768 我还加了一些注释代码,对 ...
随机推荐
- Ubuntu安装Hadoop
系统:Ubuntu16.04 JDK:jdk-8u201 Hadoop:3.1.2 一.安装JDK https://www.cnblogs.com/tanrong/p/10641803.html 二. ...
- python:PATH、PYTHONPATH 和 sys.path 的区别
python:PATH.PYTHONPATH 和 sys.path 的区别 共同点 所有在它们的路径里面的 moduel 都可以被 import PATH 在 PATH 中的一些命令,例如 *.exe ...
- 欧朋Opera 浏览器(打不开百度)提示“您的连接不是私密连接”,解决办法
它网页报错SSL.提示“您的连接不是私密连接” 打开opera://net-internals/#hsts,操作如下图片,三步以后,ok 如果是其他外国浏览器,用这个办法也有效,可以把前面的 oper ...
- 关于<服务器>定义
定义: 服务器,也称伺服器,是提供计算服务的设备.由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力. 服务器的构成:包括处理器.硬盘.内存.系统总线等,和 ...
- SVM python代码自实践
import numpy as np import matplotlib.pyplot as plt #创造数据 x = [-2,6,-2,7,-3,3,0,8,1,10,2,12,2,5,3,6,4 ...
- Python之tkinter:调用python库的tkinter带你进入GUI世界(二)——Jason niu
#tkinter:tkinter应用案例之便签框架LabelFrame的应用将组件(多选按钮)放到一个框架里 from tkinter import * root=Tk() root.title(&q ...
- H5分享功能
web端分享功能 https://www.cnblogs.com/sdcs/p/8328367.html H5分享功能 公司里面做web开发经常会做H5页面,今天整理分享一下. 微信公众号平台 步骤一 ...
- python3 替换字符串中指定位置字符
大家都知道字符串在python中是不可变数据类型,那么我们如何替换字符串中指定位置的字符呢? 字符串转换列表替换并转换解决: def replace_char(string,char,index): ...
- A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header
使用arduino烧写esp32模块遇到的无法烧录问题,时钟无法烧录遇到如下提示 后来搜索在如下连接找到解决方法: https://github.com/espressif/esptool/issue ...
- python中的矩阵、多维数组
2. 创建一般的多维数组 import numpy as np a = np.array([1,2,3], dtype=int) # 创建1*3维数组 array([1,2,3]) type(a ...