首页 > 代码库 > HDU 3001 Travelling 状态DP
HDU 3001 Travelling 状态DP
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 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。