zoukankan      html  css  js  c++  java
  • poj2686 状态压缩dp

      这个题的意思是给你一个m个顶点, p条边的无向图, 现在想从a走到b, 旅者也带有n张车票, 每张车票上有一定数量的马匹数量, 经过一条边必须使用车票, 且时间花费是边的长度除以马匹数量,问你最少多长时间到达b , 我们可以定义状态dp[s][u]表示从在u点持有s的车票, 那么下面就可以采用刷表法更新最短路, 代码如下:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    const int inf = 0x3f3f3f3f;
    int n, m, p, a, b;
    int t[20];
    int d[50][50];
    double dp[1<<10][32];
    
    int main()
    {
        while(scanf("%d%d%d%d%d", &n, &m, &p, &a, &b)!=EOF)
        {
            if(n+m+p+a+b == 0) break;
            for(int i=0; i<n; i++) scanf("%d", &t[i]);
            memset(d, -1, sizeof(d));
            for(int i=0; i<p; i++)
            {
                int x, y, z;
                scanf("%d%d%d", &x, &y, &z);
                d[x][y] = d[y][x] = z;
            }
            for(int i=0; i<(1<<(n+1)); i++)
            for(int j=0; j<=m+2; j++) dp[i][j] = inf;
            dp[(1<<n)-1][a] = 0;
            double res = (double)inf;
            for(int s=(1<<n)-1; s>=0; s--)
            {
                for(int u=1; u<=m; u++)
                {
                    res = min(res, dp[s][b]);
                    for(int i=0; i<n; i++)
                    if(((s>>i)&1) == 1)
                    for(int v=1; v<=m; v++)
                    if(d[u][v]>=0)
                    {
                        //printf("u = %d, v = %d
    ", u, v);
                        int ns = s&~(1<<i);
                        dp[ns][v] = min(dp[ns][v], dp[s][u]+d[u][v]/(double)t[i]);
                    }
                }
            }
            if(res == inf)
            {
                printf("Impossible
    ");
            }
            else
                printf("%.5f
    ", res);
        }
        return 0;
    }

        另外一个版本的代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    const int inf = 0x3f3f3f3f;
    int n, m, p, a, b;
    int t[40];
    struct edge { int v, cost; };
    vector<edge> G[50];
    double dp[(1<<10)][32];
    
    int main()
    {
        while(scanf("%d%d%d%d%d", &n, &m, &p, &a, &b) != EOF)
        {
            if(n+m+p+a+b == 0) break;
            for(int i=0; i<n; i++) scanf("%d", &t[i]);
            for(int i=0; i<=m; i++) G[i].clear();
            for(int i=0; i<p; i++)
            {
                int x, y, z;
                scanf("%d%d%d", &x, &y, &z);
                G[x].push_back((edge){y, z});
                G[y].push_back((edge){x, z});
            }
            for(int i=0; i<(1<<(n+1)); i++)
            for(int j=0; j<=m; j++) dp[i][j] = inf;
            double res = inf;
            dp[(1<<n)-1][a] = 0;
            for(int s=(1<<n)-1; s>=0; s--)
            {
                for(int u=1; u<=m; u++) if(dp[s][u] != inf)
                {
                    res = min(res, dp[s][b]);
                    for(int i=0; i<n; i++) if(((s>>i)&1) == 1)
                    {
                        for(int j=0; j<G[u].size(); j++)
                        {
                            int v = G[u][j].v, cost = G[u][j].cost;
                            dp[s&~(1<<i)][v] = min(dp[s&~(1<<i)][v], dp[s][u]+(double)cost/t[i]);
                        }
                    }
                }
            }
            if(res == inf)
            {
                printf("Impossible
    ");
            }
            else
                printf("%.5f
    ", res);
         }
        return 0;
    }
  • 相关阅读:
    js showModalDialog参数传递
    1:N 关系
    1:N 关系 视图查找
    设置IE主页和添加收藏夹的功能
    GridView和DataFormatString网站技术
    JS 的table属性操作,
    GridView帮定数据显示数据的技巧
    后台取相同name值的问题
    赶集网CEO杨浩涌:倒闭没那么容易
    用户数据泄露案告破:嫌疑人已抓 CSDN受到警告
  • 原文地址:https://www.cnblogs.com/xingxing1024/p/5251120.html
Copyright © 2011-2022 走看看