TSP问题,不懂就是每个点最多访问两次,最少访问一次。
所以,我们可以用三进制来当做状态。
这个题练习了一下三进制……0、1、2
1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <cmath>
6 #include <algorithm>
7 #include <string>
8 #include <queue>
9 #include <stack>
10 #include <vector>
11 #include <map>
12 #include <set>
13 #include <functional>
14 #include <time.h>
15
16 using namespace std;
17
18 const int INF = 1<<30;
19
20 int Matrix[15][15];
21 int base[70000][15]; //base[i][j]表示 数字i从右边第j位起的三进制值
22 int dp[70000][15];
23 int thr[20];
24 int n, m;
25
26 inline bool check(int x) { //判断是否是最终状态
27 for (int i = 0; i < n; i++) if (!base[x][i]) //如果某一位是0则不是
28 return false;
29 return true;
30 }
31
32 inline void update(int st, int u, int v) { //更新状态
33 int &now = dp[st+thr[v]][v];
34 if (now<0) now = dp[st][u]+Matrix[u][v];
35 else now = min(now, dp[st][u]+Matrix[u][v]);
36 }
37
38 void init() {
39 thr[0] = 1;
40 for (int i = 1; i < 20; i++)
41 thr[i] = thr[i-1]*3;
42 for (int i = 0; i < 70000; i++) {
43 int j = i, k = 0;
44 while (j) {
45 base[i][k++] = j%3;
46 j /= 3;
47 }
48 }
49 }
50
51 void input() {
52 memset(Matrix, -1, sizeof(Matrix));
53 for (int i = 0; i < m; i++) {
54 int x, y, c;
55 scanf("%d%d%d", &x, &y, &c);
56 x--; y--;
57 if (-1==Matrix[x][y]) Matrix[x][y] = Matrix[y][x] = c;
58 else Matrix[x][y] = Matrix[y][x] = min(Matrix[x][y], c);
59 }
60 }
61
62 void solve() {
63 memset(dp, -1, sizeof(dp));
64 for (int i = 0; i < n; i++)
65 dp[thr[i]][i] = 0;
66 for (int i = 1; i < thr[n]; i++) {
67 for (int u = 0; u < n; u++) if (dp[i][u]>-1) { //此状态可达
68 for (int v = 0; v < n; v++) if (u!=v && base[i][v]<2 && Matrix[u][v]>-1){ //可以转移到下一个状态
69 update(i, u, v); //更新下一个状态
70 }
71 }
72 }
73
74 int ans = -1;
75 for (int i = 0; i < thr[n]; i++) if (check(i)) {
76 for (int j = 0; j < n; j++) if (-1 < dp[i][j]) {
77 ans = ans>-1 ? min(ans, dp[i][j]) : dp[i][j];
78 }
79 }
80 printf("%d\n", ans);
81 }
82
83 int main() {
84 #ifdef Phantom01
85 freopen("HDU3001.txt", "r", stdin);
86 #endif //Phanaom01
87
88 init();
89 while (scanf("%d%d", &n, &m)!=EOF) {
90 input();
91 solve();
92 }
93
94 return 0;
95 }
HDU3001
时间: 2024-10-06 03:32:49