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;
    }
    
    
  • 相关阅读:
    WPF关于“在“System.Windows.Markup.StaticResourceHolder”上提供值时引发了异常。”问题解决办法
    未知的生成错误 因为没有预加载,所以无法解析程序集 GalaSoft.MvvmLight
    C#中的??是什么意思
    WIN10使用管理员权限运行VS2013
    路飞项目
    DRF
    Vue
    dsdffd
    python学习第45天
    python学习第44天
  • 原文地址:https://www.cnblogs.com/flightless/p/13397597.html
Copyright © 2011-2022 走看看