• 哈密顿回路


    旅行商问题

    求解从一点出发经过其它各点仅一次并回到出发点的最短路径
    当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;
    }
    
    
  • 相关阅读:
    IE版本
    我的班级首页,九九计四
    三层体系结构的ASP应用程序
    寻实习有悟
    servlet中请求转发(forword)与重定向(sendredirect)的区别
    Android之Providing Resources(提供资源)
    PHP用SAX解析XML
    Android之Handling Runtime Changes(处理运行时更改)
    Android 之Accessing Resource(资源调用)
    实习第一天
  • 原文地址:https://www.cnblogs.com/flightless/p/13397597.html
Copyright © 2020-2023  润新知