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

Leohh發表於2017-08-16

題目連結: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 }

 

相關文章