HDU 5067 Harry And Dig Machine:TSP(旅行商)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5067

题意:

  给你一个n*m的地图,地图上标着对应位置的石子数。你从左上角出发,每次可以向上下左右四个方向移动。你要遍历所有有石子的地方,并返回起点。问你最少的移动步数。

题解:

  简化问题:

    只保留起点和有石子的点,预处理出保留点两两之间的最短路(曼哈顿距离),将矩阵转化为一个无向图。

    原题变为了TSP模板题。

  然后套模板就好了。。。

  三重for循环,分别枚举state、当前位置i、下一步位置j。

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <math.h>
 5 #define MAX_N 55
 6 #define MAX_S (1<<15)
 7 #define INF 10000000
 8 
 9 using namespace std;
10 
11 int n,m;
12 int cnt;
13 int ans;
14 int x[MAX_N];
15 int y[MAX_N];
16 int dis[MAX_N][MAX_N];
17 int dp[MAX_S][MAX_N];
18 
19 void read()
20 {
21     cnt=0;
22     int temp;
23     for(int i=0;i<n;i++)
24     {
25         for(int j=0;j<m;j++)
26         {
27             cin>>temp;
28             if(temp>0 || (i==0 && j==0))
29             {
30                 x[cnt]=i;
31                 y[cnt]=j;
32                 cnt++;
33             }
34         }
35     }
36 }
37 
38 void cal_dis()
39 {
40     for(int i=0;i<cnt;i++)
41     {
42         for(int j=0;j<cnt;j++)
43         {
44             dis[i][j]=fabs(x[i]-x[j])+fabs(y[i]-y[j]);
45         }
46     }
47 }
48 
49 void solve()
50 {
51     cal_dis();
52     memset(dp,-1,sizeof(dp));
53     dp[0][0]=0;
54     for(int state=0;state<(1<<cnt);state++)
55     {
56         for(int i=0;i<cnt;i++)
57         {
58             if(dp[state][i]!=-1)
59             {
60                 for(int j=0;j<cnt;j++)
61                 {
62                     if( !((state>>j)&1) && (dp[state|(1<<j)][j]==-1 || dp[state|(1<<j)][j]>dp[state][i]+dis[i][j]) )
63                     {
64                         dp[state|(1<<j)][j]=dp[state][i]+dis[i][j];
65                     }
66                 }
67             }
68         }
69     }
70     ans=INF;
71     for(int i=0;i<cnt;i++)
72     {
73         if(dp[(1<<cnt)-1][i]!=-1) ans=min(ans,dp[(1<<cnt)-1][i]+dis[i][0]);
74     }
75 }
76 
77 void print()
78 {
79     cout<<ans<<endl;
80 }
81 
82 int main()
83 {
84     while(cin>>n>>m)
85     {
86         read();
87         solve();
88         print();
89     }
90 }
原文地址:https://www.cnblogs.com/Leohh/p/7368551.html