• 《算法竞赛进阶指南》 第一章 Acwing 91. 最短Hamilton路径


    地址  https://www.acwing.com/problem/content/93/

    给定一张 n 个点的带权无向图,点从 0∼n−1 标号,求起点 0 到终点 n−1 的最短 Hamilton 路径。
    
    Hamilton 路径的定义是从 0 到 n−1 不重不漏地经过每个点恰好一次。
    
    输入格式
    第一行输入整数 n。
    
    接下来 n 行每行 n 个整数,其中第 i 行第 j 个整数表示点 i 到 j 的距离(记为 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 路径的长度。
    
    数据范围
    1≤n≤20
    0≤a[i,j]≤107
    输入样例:
    5
    0 2 4 5 1
    2 0 6 5 3
    4 6 0 8 3
    5 5 8 0 5
    1 3 3 5 0
    输出样例:
    18

    解法

    Hamilton路径就是指定起点和终点的不重不漏的遍历每个点的路径

    那么这题的暴力做法是 深度或者广度搜索出 0~n-1点的各种排列组合 然后遍历得出最短路径

    复杂度过高  排列组合的复杂度是n!  计算最短路径遍历n个点  总复杂度就是 O(n*n!)

    对于 0 1 2 3 4 5。

    0 和 5 是确定的开头和结尾 .

    如果倒数第二个点是4号点

    那么 我们只关心 经过 1 2 3 到4号点的最短路径  0-> 123->4->5

    如果倒数第二个点是3号点

    那么 我们只关心 经过 1 2 4 到3号点的最短路径  0-> 124->3->5

    我们使用某个数据结构记录 某个路径下以x点结尾最短路径就可以避免重复计算 达到加速目的

    我们使用状态压缩的方案 使用二进制数标记某点是否被经过,0表示未经过,1表示经过

    那么经过一系列路径state 最后重点为x的最短路径表达为  dp[state][x]

    yi= state表示的路径上的非x的各个点

    dp[state][x] = min( dp[state-yi][x] + distance[yi][x] )

    #include <iostream>
    #include <memory.h>
    using namespace std;
    
    
    const int N =30;
    const int M = 1<<20;
    
    int dis[N][N];
    int dp[M][N];
    
    int n;
    
    int main(){
        cin >> n;
        
        for(int i =0;i<n;i++){
            for(int j = 0;j<n;j++){
                cin >> dis[i][j];    
            }
        }
        
        memset(dp,0x3f,sizeof dp);
        dp[1][0]=0;
        
        for(int i =0;i< (1<<n);i++){
            for(int j = 0;j<n;j++){
                if(i>>j&1){
                    for(int k = 0; k < n;k++){
                        if((i-(1<<j))>>k&1){
                            dp[i][j] = min(dp[i][j],dp[(i-(1<<j))][k]+dis[k][j]);
                        }
                    }
                }
            }
        }
        
        cout << dp[(1<<n)-1][n-1] << endl;
        
        return 0;
    }
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    【学习笔记】查看CUDA版本
    如果Visual Studio太大,不妨还是用VSCode开发C#项目吧
    Visual Studio npm配置淘宝镜像
    c++读写锁--读者写者问题
    c++内存对象模型--vs2017下的分析,32位
    android作业
    android连接数据库
    android第十周(增删改查)
    android-购物车
    android计算器
  • 原文地址:https://www.cnblogs.com/itdef/p/14565540.html
Copyright © 2020-2023  润新知