zoukankan      html  css  js  c++  java
  • 哈密顿回路

    旅行商问题

    求解从一点出发经过其它各点仅一次并回到出发点的最短路径
    当n的个数不到时,可通过状压dp求解

    状态压缩

    将每个点是否访问过编码为0或1,那么当n=4时,访问所有点后的状态为1111,初始时状态为0001。
    达到每个状态的最后一步可能是从第1,2,3,4个位置转移过来的,因此我们需要记录达到当前状态时,上次访问的点
    由此我们可以写出状态转移方程
    dp[t][j]=min(dp[t][j],dp[s][i]+dis[i][j])
    由状态转移方程可知我们需要枚举状态s,转移到状态t的上一步j,以及状态s的上一步i

    #include<iostream>
    #include<cstdio>
    #include<bits/stdc++.h>
    using namespace std;
    const int INF=0x3f3f3f3f;
    int dis[22][22];
    //dp[i][j]表示已访问状态为i,上次访问点为j的最小距离
    int main()
    {
        int n;
        scanf("%d",&n);
        vector<vector<int>> dp(1<<(n),vector<int>(n+1,INF));
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&dis[i][j]);
            }
        }
        dp[1][1]=0;
        //枚举状态s,更新从s经过i到下一状态t的最短路径
        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(!(s&(1<<(j-1)))){
                            int t=(s|(1<<(j-1))); //新状态
                            //cout<<i<<" "<<j<<" "<<s<<" "<<t<<endl;
                            dp[t][j]=min(dp[t][j],dp[s][i]+dis[i][j]);
                        }
                    }
                }
            }
        }
        int ans=INF;
        for(int i=2;i<=n;i++){
            ans=min(ans,dp[(1<<n)-1][i]+dis[i][1]);
        }
        printf("%d
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    为什么MySQL数据库索引选择使用B+树?
    nginx负载均衡策略
    视频笔记
    mysql show full processlist 分析问题
    Git利用命令行提交代码步骤
    zend studio远程自动上传代码并执行
    CentOS7 通过YUM安装MySQL5.7 linux
    PHP的按位运算符是什么意思
    git 分支操作
    php 技术知识点汇总
  • 原文地址:https://www.cnblogs.com/flightless/p/13397597.html
Copyright © 2011-2022 走看看