zoukankan      html  css  js  c++  java
  • AcWing 91. 最短Hamilton路径(状压DP)

    给定一张 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
    题目

    题解:

    暴力时间复杂度O(n*n!)

    状压DP的状态转移方程为

    f[i][j]=min(f[i][j],f[i-(1<<j)][k]+a[k][j])

    其中f[i][j],i表示已经走过的点的集合,j表示当前停留在j点。

    枚举状态转移的中间点k。时间复杂度O(20*20^20)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm> 
    using namespace std;
    
    const int N=20,M=1<<20;
    
    int f[M][N];
    int a[N][N];
    
    int main()
    {
        int n;
        cin>>n;
        for(int i=0;i<n;i++)
         for(int j=0;j<n;j++)
          cin>>a[i][j];
        memset(f,0x3f,sizeof f);
        f[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)
                    {
                        f[i][j]=min(f[i][j],f[i-(1<<j)][k]+a[k][j]);
                    }
                }
            }
        }
        cout<<f[(1<<n)-1][n-1];
        return 0;
    }
  • 相关阅读:
    SEVERE: One or more listeners failed to start.
    springboot junit单元测试报错
    mybatis 日期查询datetime
    设计模式详解之程序设计六大原则
    非maven项目 idea project structure
    jdbcType DATE和TIMESTAMP区别
    mysql 保存23:59:59 自动加一秒
    1、在linux服务器centos虚拟机搭建nginx网站
    QRCode 生成二维码
    CSS3的calc()使用
  • 原文地址:https://www.cnblogs.com/zzyh/p/14663658.html
Copyright © 2011-2022 走看看