亲宝软件园·资讯

展开

牛客在线编程_毕业旅行问题

Keane1998 人气:1

题目地址
求从点1出发经过其他点各一次再回到点1的最短路,即求哈密顿回路长度。

  • 使用状压dp,定义dp[s][i]表示已访问点的状态为s,上一个访问的点为i的最短路长度,然后枚举上一个状态和最后经过的点,再枚举没有在状态中出现的中转点,新状态取个min。
  • 如果不限制只经过每个点一次,可以先用floyd求一次多源最短路。
  • 卡内存,可以用java或者用vector<vector<int>> (N,vector<int>(M,INF));

code

#include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int dis[22][22];
int n;
int main(){
    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;
    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)));
                        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\n",ans);
    return 0;
}

加载全部内容

相关教程
猜你喜欢
用户评论