http://acm.hdu.edu.cn/showproblem.php?pid=5067
规定起点和终点的tsp问题,解法依然是状态压缩dp,在初始化和计算答案的时候略做改动即可
#include <iostream> #include <cstdio> #include <map> #include <cstring> using namespace std ; const int INF=0xfffffff ; int n,m ; int M[55][55] ; int dis[15][15] ; int dp[1<<15][15] ; int ABS(int x){return x>0?x:-x ;} struct point { int x,y ; }p[15] ; int cal(point a,point b) { return ABS(a.x-b.x)+ABS(a.y-b.y) ; } int main() { while(~scanf("%d%d",&n,&m)) { for(int i=0 ;i<n ;i++) { for(int j=0 ;j<m ;j++) { scanf("%d",&M[i][j]) ; } } int cnt=0 ; for(int i=0 ;i<n ;i++) { for(int j=0 ;j<m ;j++) { if(i==0 && j==0)continue ; if(M[i][j]) { p[cnt].x=i ; p[cnt++].y=j ; } } } for(int i=0 ;i<15 ;i++) for(int j=0 ;j<15 ;j++) dis[i][j]=INF ; for(int i=0 ;i<cnt ;i++) { for(int j=0 ;j<cnt ;j++) { if(i==j) { dis[i][j]=0 ; continue ; } dis[i][j]=cal(p[i],p[j]) ; } } point s ; s.x=0 ;s.y=0 ; for(int i=0 ;i<(1<<15) ;i++) for(int j=0 ;j<15 ;j++) dp[i][j]=INF ; for(int i=0 ;i<cnt ;i++) { dp[1<<i][i]=cal(s,p[i]) ; } for(int i=0 ;i<(1<<cnt) ;i++) { for(int j=0 ;j<cnt ;j++) { if(i&(1<<j)) { for(int k=0 ;k<cnt ;k++) { if(dis[k][j]==INF || !(i&(1<<k)))continue ; dp[i][j]=min(dp[i][j],dp[i^(1<<j)][k]+dis[k][j]) ; } } } } int ans=INF ; for(int i=0 ;i<cnt ;i++) { ans=min(ans,dp[(1<<cnt)-1][i]+cal(p[i],s)) ; } if(ans==INF) { puts("0") ; continue ; } printf("%d\n",ans) ; } return 0 ; }
时间: 2024-10-05 16:16:40