• 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 }
  • 相关阅读:
    POJ3889Fractal Streets
    POJ3263 Tallest Cow
    tyvjP1288 飘飘乎居士取能量块
    洛谷P3369 【模板】普通平衡树(Treap/SBT)
    洛谷P1063 能量项链 [2006NOIP提高组]
    洛谷P1541 乌龟棋 [2010NOIP提高组]
    POJ3322 Bloxorz I
    BZOJ1218:[HNOI2003]激光炸弹
    TyvjP1266 费解的开关
    洛谷P3070 [USACO13JAN]岛游记Island Travels
  • 原文地址:https://www.cnblogs.com/romaLzhih/p/12315130.html
Copyright © 2020-2023  润新知