5796: 最短Hamilton路径(状压dp)

5796: 最短Hamilton路径 分享至QQ空间

时间限制(普通/Java):5000MS/15000MS     内存限制:250000KByte
总提交: 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 }
View Code

猜你喜欢

转载自www.cnblogs.com/qq-1585047819/p/11727950.html