HDU 3001 Travelling:TSP(旅行商)
阿新 • • 發佈:2017-08-15
sta init using 多少 b- upd eof == als
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3001
題意:
有n個城市,m條雙向道路,每條道路走一次需要花費路費v。你可以將任意一個城市作為起點出發,然後遍歷每一個城市,並保證同一個城市最多經過2次。問你遍歷這些城市的最小費用是多少。
題解:
傳統的TSP問題中,每個城市只能經過一次,做法為三重for循環,分別枚舉城市的state、現在所處位置i、下一步要到達的城市j。
核心Code:
1 memset(dp,-1,sizeof(dp));
2 dp[1<<start][start]=0;
3 for(int state=0 ;state<(1<<n);state++)
4 {
5 for(int i=0;i<n;i++)
6 {
7 if(dp[state][i]!=-1)
8 {
9 for(int j=0;j<n;j++)
10 {
11 if(i!=j && !((state>>j)&1))
12 {
13 if(dp[state|(1<<j)][j]==-1 || dp[state|(1<<j)][j]>dp[state][i]+dis[i][j])
14 {
15 dp[state|(1<<j)][j]=dp[state][i]+dis[i][j];
16 }
17 }
18 }
19 }
20 }
21 }
在這道題中,與傳統TSP的唯一區別是每個城市最多經過的次數由1次變為了2次。那麽表示每座城市的狀態state也應該相應改為用三進制數表示,每一位上的數字代表對應城市已經經過的次數。
所以把所有的二進制改為三進制就好啦 ( ̄▽ ̄)~*
註:不用對於每一個起點分別求一次dp,會T。。。在開始要把所有的dp[update(0, i)][i] = 0
AC Code:
1 #include <iostream>
2 #include <stdio.h>
3 #include <string.h>
4 #include <queue>
5 #define MAX_N 15
6 #define MAX_S 60000
7 #define INF 100000000
8
9 using namespace std;
10
11 const int POW[]={1,3,9,27,81,243,729,2187,6561,19683,59049,177147,531441,1594323,4782969};
12
13 int n,m;
14 int a,b,v;
15 int ans;
16 int dis[MAX_N][MAX_N];
17 int dp[MAX_S][MAX_N];
18
19 void init()
20 {
21 for(int i=0;i<n;i++)
22 {
23 for(int j=0;j<n;j++)
24 {
25 dis[i][j]=INF;
26 if(i==j) dis[i][j]=0;
27 }
28 }
29 }
30
31 void read()
32 {
33 for(int i=0;i<m;i++)
34 {
35 cin>>a>>b>>v;
36 dis[a-1][b-1]=min(dis[a-1][b-1],v);
37 dis[b-1][a-1]=min(dis[b-1][a-1],v);
38 }
39 }
40
41 int query(int a,int k)
42 {
43 return a/POW[k]%3;
44 }
45
46 int update(int a,int k)
47 {
48 return a+POW[k];
49 }
50
51 bool check(int state)
52 {
53 for(int i=0;i<n;i++)
54 {
55 if(query(state,i)==0) return false;
56 }
57 return true;
58 }
59
60 void solve()
61 {
62 ans=INF;
63 memset(dp,-1,sizeof(dp));
64 for(int i=0;i<n;i++)
65 {
66 dp[update(0,i)][i]=0;
67 }
68 for(int state=0;state<POW[n];state++)
69 {
70 for(int i=0;i<n;i++)
71 {
72 if(dp[state][i]!=-1)
73 {
74 for(int j=0;j<n;j++)
75 {
76 if(i!=j && query(state,j)<2)
77 {
78 int nex=update(state,j);
79 if(dp[nex][j]==-1 || dp[nex][j]>dp[state][i]+dis[i][j])
80 {
81 dp[nex][j]=dp[state][i]+dis[i][j];
82 }
83 }
84 }
85 if(check(state)) ans=min(ans,dp[state][i]);
86 }
87 }
88 }
89 }
90
91 void print()
92 {
93 if(ans==INF) cout<<-1<<endl;
94 else cout<<ans<<endl;
95 }
96
97 int main()
98 {
99 while(cin>>n>>m)
100 {
101 init();
102 read();
103 solve();
104 print();
105 }
106 }
HDU 3001 Travelling:TSP(旅行商)