牛客在線編程_畢業旅行問題


題目地址
求從點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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM