【Acwing91】最短Hamilton路径详细题解

news2024/11/16 16:00:23

题目描述

题目分析

首先我们来分析暴力做法,此时最大需要遍历(n=20)20个顶点的排列方式,总共计算的次数为20!,数量级远远大于10^8,显然是不合理的。

此时,我们可以对上述dfs遍历的众多情况进行剪枝,去掉没有用的情况。

假设有4个顶点,1,2,3,4,5,有以下若干路径

1--2--3--4--5   路径总长度为18

1--3--2--4--5   路径总长度为20

......

可以发现比如对于第四个点,在这个点之前经过的其他点的顺序可以是无关紧要的,这里的两条路径都是经过了1,2,3只不过顺序不同导致最终的路径总长度不同,所以对于经过一个特定的点集的路径,只需要知道并存储这种情况之下的最短路径即可。比如说上述,设点集A={1,2,3},令m[A,4]代表已经经过点集A,并且终点落在第四个点的所有路径。m的表示法是最开始暴力思想的体现,即存储所有的路径,但是经过刚才的分析,进行剪枝操作,可以令f[A,4]代表已经经过点集A,并且终点落在第四个点的最小路径长度,这也是本题用到的状态表示。

下面的问题是:如何表示点集A?

可以使用经典的二进制状态压缩操作:不再阐述统一的定义,直接具几个状态表示的实例,我相信就能清楚了:

f[11,2]:11的二进制表示为1011,所以代表已经经过第1,2,4个点并且终点为2的最短路径长度

f[7,2]:7的二进制表示为111,所以代表已经经过第1,2,3个点并且终点为2的最短路径长度

f[17,5]:7的二进制表示为10001,所以代表已经经过第1,5个点并且终点为5的最短路径长度

有了状态表示,状态计算也非常简单:

f[i,j]=min(f[i-{j},k]+weight[k,j])  k=1~n

所以在代码中最外层遍历不同的点集情况,最多为2^20,,第二层遍历不同的终点,20种情况,第三层遍历不同的中间结点,20种情况,总时间最多为4*10^8

注意第一层遍历和第二层遍历需要加一个判断条件:if(i>>j&1)判断点集i中是否包含点j

第二层遍历和第三层遍历也需要加一个判断条件:if(i>>k&1)判断点集i中是否包含点k,为什么不是判断点集i-{j}中是否包含k呢,因为j==k的时候,对整个结果没有影响

代码

#include<iostream>
#include<cstring>
using namespace std;
const int N=20,M=1<<N;
int weight[N][N];
int f[M][N];
int n;
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            cin>>weight[i][j];
    memset(f,0x3f,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)
                for(int k=0;k<n;k++)
                    if(i>>k&1)
                    f[i][j]=min(f[i][j],f[i-(1<<j)][k]+weight[k][j]);
    cout<<f[(1<<n)-1][n-1];
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/935253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot项目在启动后自动关闭

问题描述&#xff1a; 今天搭建了一个SpringBoot项目&#xff0c;但是在启动之后就自行关闭了&#xff0c;就像下面这样&#xff1a; 原因分析&#xff1a;在创建SpringBoot项目的时候&#xff0c;Web的依赖没有导入&#xff0c;默认以普通java项目运行导致的终止。 解决方案…

【Tkinter系列01/5】界面初步和布局

一、说明 一般来说&#xff0c;界面开发中&#xff0c;如果不是大型的软件&#xff0c;就不必用QT之类的实现&#xff0c;用Tkinter已经足够&#xff0c;然而即便是Tkinter规模不大&#xff0c;也需要一个系统专业的学习过程&#xff0c;本篇将是对Tkinter系列介绍的一篇博文。…

SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录(第五天)MyBatis的注解开发

SSM框架的学习与应用(Spring Spring MVC MyBatis)-Java EE企业级应用开发学习记录&#xff08;第五天&#xff09;MyBatis的注解开发 ​ 昨天我们深入学习了MyBatis多表之间的关联映射&#xff0c;了解掌握了一对一关联映射&#xff0c;一对多关联映射&#xff0c;嵌套查询方…

基于Milvus Cloud的相似穿搭推荐系统教程——图像分割

作为一个大众眼中的“非典型程序员”,我喜欢拥抱时尚和潮流,比如我经常在演讲时穿粉色裤子,这甚至已经成为一个标志性打扮。某天又逢主题演讲日,我站在衣柜前挑选上衣的时候,忽然灵光乍现:有没有可能借助 Milvus Cloud找到和我穿搭风格最为相似的明星呢? 这个想法在我脑…

不系安全带抓拍自动识别

不系安全带抓拍自动识别系统通过yolo系列算法框架模型利用高清摄像头&#xff0c;不系安全带抓拍自动识别算法对高空作业场景进行监控&#xff0c;当检测到人员未佩戴安全带时会自动抓拍并进行告警记录。YOLO系列算法是一类典型的one-stage目标检测算法&#xff0c;其利用ancho…

Day44|leetcode 518.零钱兑换II、377. 组合总和 Ⅳ

完全背包理论基础 视频链接&#xff1a;带你学透完全背包问题&#xff01; 和 01背包有什么差别&#xff1f;遍历顺序上有什么讲究&#xff1f;_哔哩哔哩_bilibili 完全背包与01背包不同的地方就是&#xff1a;01背包每种物品只能取一次&#xff0c;而完全背包每种物品可以取…

【排序】快速排序(前后指针法)—— 考的最少的一种算法

以从小到大的顺序进行说明。 前后指针法 是指对于一个数组&#xff0c;定义前后各一个指针&#xff08;prev 和 cur&#xff09; prev用于卡一个比基准值大的值进行交换cur用于向前遍历出比基准值小的&#xff0c;和prev进行交换 图解 初始化 选出基准值4 如果cur 所在的值…

重要岗位人员脱岗预警 脱岗监测预警算法

重要岗位人员脱岗预警 脱岗监测预警算法通过yolov8网络模型深度学习算法&#xff0c;重要岗位人员脱岗预警 脱岗监测预警算法对现场人员行为进行实时监测和识别&#xff0c;通过算法识别脱岗、睡岗和玩手机等异常行为&#xff0c;实现对人员行为的预警和告警。YOLOv8是目前YOLO…

java八股文面试[多线程]——什么是守护线程

知识来源&#xff1a; 【2023年面试】什么是守护线程_哔哩哔哩_bilibili

【Linux】DNS系统,ICMP协议,NAPT技术

遏制自己内心的知识优越感&#xff0c;才能让你发自内心的去尊重他人&#xff0c;避免狂妄自大&#xff0c;才能让你不断的丰富自己的内心。 文章目录 一、DNS系统1.DNS服务器返回域名对应的ip2.使用dig工具分析DNS过程3.浏览器中输入url后发生的事情&#xff1f; 二、ICMP协议…

【Springboot】| 从深入自动配置原理到实现 自定义Springboot starter

目录 一. &#x1f981; 前言二. &#x1f981; Spring-boot starter 原理实现分析2.1 自动配置原理 三. &#x1f981; 操作实践3.1 项目场景3.2 搭建项目3.3 添加相关依赖3.4 删除一些不需要的东西3.5 发邮件工具类逻辑编写3.6 创建相关配置类3.7 创建 Spring.factories 文件…

java八股文面试[多线程]——死锁、活锁、饥饿

DCL双重锁&#xff1a;TODO 如何预防死锁&#xff1a; 如何查看线程死锁&#xff1a; 知识来源&#xff1a; 【2023年面试】描述一下线程安全活跃态问题&#xff0c;以及竞态条件_哔哩哔哩_bilibili 【2023年面试】如何预防死锁_哔哩哔哩_bilibili 【并发与线程】阿里一面&…

手把手教你用 ANSYS workbench

ANSYS Workbench ANSYS Workbench是一款基于有限元分析&#xff08;FEA&#xff09;的工程仿真软件。其基本概念包括&#xff1a; 工作区&#xff08;Workspace&#xff09;&#xff1a;工程仿真模块都在此区域内&#xff0c;包括几何建模、网格划分、边界条件设置、分析求解等…

锐捷PPP协议原理--尚文网络敏姐

PPP 点对点协议 目录 PPP 点对点协议 PPP 简介 PPP协议层介绍&#xff1a; PPP协议工作原理 第一个阶段&#xff1a;LCP协商 第二阶段&#xff1a;身份认证阶段 第三阶段&#xff1a;NCP协商阶段 PPP配置实验 PAP的单向认证&#xff1a; PAP双向认证 CHAP的单向认证&#…

数组名和函数名是指针?指针和引用底层一样?

在2023/8/26日晚上&#xff0c;我看到一个所谓“典”的视频&#xff0c;一开始还没太在意&#xff0c;后面想了想发现我貌似也一直犯了以下的错误&#xff0c;而错误的原因在于我在新手阶段学习C/C并不是查阅文档扎好脚步学习的&#xff0c;而是被铺天盖地的新手学习基础教程里…

图书管理系统Java书店进销存jsp源代码MySQL

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 图书管理系统 系统有1权限&#xff1a;管理员 用所技…

5.网络原理之初识

文章目录 1.网络发展史1.1独立模式1.2网络互连1.3局域网LAN1.3.1基于网线直连1.3.2基于集线器组建1.3.3基于交换机组建1.3.4基于交换机和路由器组建1.3.4.1路由器和交换机区别 1.4广域网WAN 2.网络通信基础2.1IP地址2.2端口号2.3认识协议2.4五元组2.5 协议分层2.5.1 分层的作用…

weak_ptr是怎么探知对象生死的

weak_ptr是C智能指针中的一种。它用于解决共享所有权的问题&#xff0c;并且可以避免因循环引用而导致的内存泄漏。 weak_ptr本身并不承担对象的所有权&#xff0c;它指向由shared_ptr管理的对象。与shared_ptr不同&#xff0c;weak_ptr并不会增加计数器来计算对象的引用次数。…

【30天熟悉Go语言】11 数组的全方位使用与解析

作者&#xff1a;秃秃爱健身&#xff0c;多平台博客专家&#xff0c;某大厂后端开发&#xff0c;个人IP起于源码分析文章 &#x1f60b;。 源码系列专栏&#xff1a;Spring MVC源码系列、Spring Boot源码系列、SpringCloud源码系列&#xff08;含&#xff1a;Ribbon、Feign&…

工厂机械臂人员闯入自动预警

工厂机械臂人员闯入自动预警系统通过yolov8系列网络模型深度学习算法&#xff0c;工厂机械臂人员闯入自动预警算法实时监测工作区域内的人员位置和机械臂设备的运行状态&#xff0c;实现对人员闯入的识别和预警。一旦系统检测到人员闯入作业区域&#xff0c;立即发出警报并同步…