zoukankan      html  css  js  c++  java
  • DAG求最短路--TSP变形--状压dp

    DAG状压dp的一种

    题目:

    $m$个城市,$n$张车票,第i张车票上的时间是$t_i$, 求从$a$到$b$的最短时间,如果无法到达则输出“impossible”

    解法:

    考虑状态:“现在在城市$v$,此时还剩下的车票的集合为$S$”这样的状态。从这个状态出发,使用一张车票移动到$i in S$移动到相邻的城市$u$,就相当于转移到了“在城市$u$,此时还剩下的车票的集合为$S/ { i }$”这个状态。

    把这个转移看成一条边,那么边上的花费就是(v-u间道路的长度)/ $t_i$。DAG上的最短路dp就能解。

    代码如下:

     1 int n, m, a, b, p;
     2 int t[MAXN];
     3 int d[MAXM][MAXM];
     4 double dp[1 << 12][MAXM];
     5 
     6 void solve() {
     7     for (int i = 0; i < 1 << n; i++) {
     8         fill(dp[i], dp[i] + m, INF);
     9     }
    10     dp[(1 << n) - 1][a - 1] = 0;
    11     double res = INF;
    12     for (int S = (1 << n) - 1; S >= 0; S--) {
    13         res = min(res, dp[S][b - 1]);
    14         for (int v = 0; v < m; v++) {
    15             for (int i = 0; i < n; i++) {
    16                 if (S >> i & 1) {
    17                     for (int u = 0; u < m; u++) {
    18                         if (d[v][u] >= 0) {
    19                             dp[S & ~(1 << i)][u] =
    20                                 min(dp[S & ~(1 << i)][u],
    21                                     dp[S][v] + (double)d[v][u] / t[i]);
    22                         }
    23                     }
    24                 }
    25             }
    26         }
    27     }
    28     if (res == INF) {
    29         printf("Impossible
    ");
    30     } else {
    31         printf("%.3f
    ", res);
    32     }
    33 }
    34 
    35 int main() {
    36 #ifndef ONLINE_JUDGE
    37     freopen("input.txt", "r", stdin);
    38 #endif  // !ONLINE_JUDGE
    39     while (scanf("%d%d%d%d%d", &n, &m, &p, &a, &b) != EOF) {
    40         if (p == 0 && m == 0 && n == 0 && a == 0 && b == 0) break;
    41         MEM(t, 0), MEM(d, 0), MEM(dp, 0);
    42         REP(i, 0, n - 1) scanf("%d", &t[i]);
    43         REP(i, 0, MAXM - 1) REP(j, 0, MAXM - 1) d[i][j] = -1;
    44         REP(i, 1, p) {
    45             int u = READ(), v = READ(), w = READ();
    46             u--, v--;
    47             d[u][v] = d[v][u] = w;
    48         }
    49         solve();
    50     }
    51     return 0;
    52 }
  • 相关阅读:
    11. Container With Most Water
    9. Palindrome Number
    375. 猜数字大小 II leetcode java
    leetcode 72 编辑距离 JAVA
    73. 矩阵置零 leetcode JAVA
    快速排序 JAVA实现
    63. 不同路径 II leetcode JAVA
    重写(override)与重载(overload)
    62 不同路径 leetcode JAVA
    leetcode 56 合并区间 JAVA
  • 原文地址:https://www.cnblogs.com/romaLzhih/p/12315130.html
Copyright © 2011-2022 走看看