5796: 最短Hamilton路径
时间限制(普通/Java):5000MS/15000MS 内存限制:250000KByte
总提交: 13 测试通过:3
View Code
总提交: 13 测试通过:3
描述
给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径。 Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次。
输入
第一行一个整数n。
接下来n行每行n个整数,其中第i行第j个整数表示点i到j的距离(一个不超过10^7的正整数,记为a[i,j])。
对于任意的x,y,z,数据保证 a[x,x]=0,a[x,y]=a[y,x] 并且 a[x,y]+a[y,z]>=a[x,z]。
输出
一个整数,表示最短Hamilton路径的长度。
样例输入
样例输出
提示
从0到3的Hamilton路径有两条,0-1-2-3和0-2-1-3。前者的长度为2+2+1=5,后者的长度为1+2+1=4
解题思路:具体看代码
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 using namespace std; 6 7 const int INF=0x3f3f3f3f; 8 int n; 9 int arr[25][25]; 10 int dp[(1<<20)+5][22]; //dp 在i状态下到达j的最短路 11 // 经过全部的状态为(1<<n)-1; 经过第i位的状态为1<<(i-1); 12 int main(){ 13 ios::sync_with_stdio(false); 14 cin>>n; 15 for(int i=1;i<=n;i++){ 16 for(int j=1;j<=n;j++){ 17 cin>>arr[i][j]; 18 } 19 } 20 memset(dp,INF,sizeof(dp)); 21 dp[0][1]=0; 22 for(int i=1;i<=(1<<n)-1;i++){ 23 for(int j=1;j<=n;j++){ 24 if(1&(i>>(j-1))==0) continue; //在i的状态下有经过j-1才可行 25 for(int k=1;k<=n;k++){ 26 if(1&(i>>(k-1))==0) continue; //在i的状态下有经过k-1在可行 27 dp[i][j]=min(dp[i][j],dp[i^(1<<(j-1))][k]+arr[k][j]); 28 } 29 } 30 } 31 cout << dp[(1<<n)-1][n] << endl; 32 return 0; 33 }