题解【AcWing91】最短Hamilton路径
看到数据范围这么小,第一眼想到爆搜。
然而这样做的复杂度是 \(\mathcal{O}(n! \times n)\) 的,明显会 TLE。
于是考虑状压 DP。
我们设 \(dp_{i,j}\) 表示当前走过的集合为 \(i\),且停留在 \(j\) 号点的最短路径长度。
转移的话可以枚举一个点 \(k\),意为从 \(k\) 号点走到点 \(j\),走过的集合变成了 \(i\)。然后就有了转移方程:\(dp_{i,j}=\min\{dp_{i-2^j,k}+a_{k,j}\}\),其中 \(a_{k,j}\) 表示点 \(k\) 到点 \(j\) 的距离。
注意点的标号从 \(0\) 开始。
这里介绍一个判断 \(j\) 号点是否出现在集合 \(i\) 中的技巧:直接判断 i >> j & 1 是否为 \(\text{true}\) 即可。
#include <bits/stdc++.h>
#define DEBUG fprintf(stderr, "Passing [%s] line %d\n", __FUNCTION__, __LINE__)
#define itn int
#define gI gi
using namespace std;
typedef long long LL;
typedef pair <int, int> PII;
typedef pair <int, PII> PIII;
inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return f * x;
}
inline LL gl()
{
LL f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return f * x;
}
int n, m, a[23][23], dp[(1 << 20) + 5][23];
int main()
{
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
n = gi();
for (int i = 0; i < n; i+=1)
for (int j = 0; j < n; j+=1)
a[i][j] = gi();
memset(dp, 0x3f, sizeof dp);
dp[1][0] = 0;
for (int i = 0; i < (1 << n); i+=1)
{
for (int j = 0; j < n; j+=1)
{
if (i >> j & 1) //判断集合 i 中是否含有 j
{
for (int k = 0; k < n; k+=1)
{
if ((i - (1 << j)) >> k & 1) //判断没有访问 j 之前有没有访问过 k
{
dp[i][j] = min(dp[i][j], dp[i - (1 << j)][k] + a[k][j]); //转移
}
}
}
}
}
printf("%d\n", dp[(1 << n) - 1][n - 1]);
return 0;
}
题解【AcWing91】最短Hamilton路径的更多相关文章
- 最短Hamilton路径【状压DP】
给定一张 nn 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. 输入 ...
- AcWing 91. 最短Hamilton路径
今天第一次在\(AcWing\)这个网站上做题,来发一下此网站的第一篇题解 传送门 思路 直接枚举的话时间复杂度为\(O(n*n!)\) 复杂度显然爆炸,所以我们用二进制枚举,这样就可以把复杂度降到\ ...
- # 最短Hamilton路径(二进制状态压缩)
最短Hamilton路径(二进制状态压缩) 题目描述:n个点的带权无向图,从0-n-1,求从起点0到终点n-1的最短Hamilton路径(Hamilton路径:从0-n-1不重不漏的每个点恰好进过一次 ...
- 『最短Hamilton路径 状态压缩DP』
状压DP入门 最短Hamilton路径 Description 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamil ...
- 位运算 - 最短Hamilton路径
给定一张 n 个点的带权无向图,点从 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 ...
- 最短Hamilton路径
题目描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每 ...
- 最短Hamilton路径-状压dp解法
最短Hamilton路径 时间限制: 2 Sec 内存限制: 128 MB 题目描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamil ...
- ACAG 0x01-4 最短Hamilton路径
ACAG 0x01-4 最短Hamilton路径 论为什么书上标程跑不过这道题-- 首先,这道题与今年CSP-S2的D1T3有着异曲同工之妙,那就是--都有$O(n!)$的做法!(大雾) 这道题的正解 ...
- 最短Hamilton路径 数位dp
最短Hamilton路径 #include<bits/stdc++.h> using namespace std; ; <<maxn][maxn]; int maps[maxn ...
随机推荐
- 高灵敏度自带DSP降噪算法的audio codec解决方案
背景调研 随着AI渗透到各行各业,人们对语音的需求也越来越大,最近一两年,各种AI音频设备如雨后春笋般冒出.各种智能AI设备的推出,意味者市场对低成本的音频采集设备越来越多.针对这种情况,我们开发 ...
- string的基本操作
在C++中,string 可以来定义一个字符串,用之前得调用下相应的库 #include<string> . 可以不用初始化字符串容量大小,系统会根据后续的赋值自动安排其容量大 ...
- 字符串转数字 (With C++)
1.stoi().stof().stod() 实现字符串转 int.float.double. stoi -> string to integer stof -> string to fl ...
- 「Flink」配置使用Flink调试WebUI
很多时候,我们在IDE中编写Flink代码,我们希望能够查看到Web UI,从而来了解Flink程序的运行情况.按照以下步骤操作即可,亲测有效. 1.添加Maven依赖 <dependency& ...
- kubernetes监控
总体设计思想 总体设计架构图Kubernetes monitoring architecture 设计介绍 监控分成两个部分 核心指标流程 包括的组件有 kubelet.resource estima ...
- gcd手写代码及STL中的使用方法
一.手写代码 inline int gcd(int x,int y){ if(y==0) return x; else return(gcd(y,x%y)); } 二.STL中的使用方法 注:在STL ...
- Android开发之adt bundle安装
这个学期开了一门手机游戏开发的课,所以就接触到了adt bundle,Android开发环境有三种方式,分别是JDK+SDK+Eclipse+ADT.JDK+adt-bundle与JDK+Androi ...
- PHPJN0001:phpmyadmin 允许密码为空 设置
phpmyadmin连接mysql数据库,出于安全考虑,默认不允许使用空密码连接数据库.因为数据库一般都设置密码访问. 但如果只是本机环境测试使用,每隔一段时间都需要填写密码,不是很方便. 如果没有修 ...
- 03.JS运算符
前言: 学习一门编程语言的基本步骤 (01)了解背景知识 (02)搭建开发环境 (03)语法规范 (04)常量和变量 (05)数据类型 (06)数据类型转换 (07)运算符7.运算符 表达式:由运 ...
- 利用Bellman-Ford算法(有向图) 判断负环
// 根据Bellman-Ford算法的原理 // 判断负环(算法的最大更新次数,应该是顶点数-1次) // 而如果存在负环,算法会一直更新下去 // 我们根据循环进行的次数,来判断负环 #inclu ...