zoukankan      html  css  js  c++  java
  • BZOJ 1003 物流运输 (动态规划 SPFA 最短路)

    1003: [ZJOI2006]物流运输
    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 5590  Solved: 2293
    [Submit][Status][Discuss]
    Description
    物流公司要把一批货物从码头A运到码头B。由于货物量比较大,需要n天才能运完。
    货物运输过程中一般要转停好几个码头。物流公司通常会设计一条固定的运输路线,
    以便对整个运输过程实施严格的管理和跟踪。由于各种因素的存在,有的时候某个
    码头会无法装卸货物。这时候就必须修改运输路线,让货物能够按时到达目的地。
    但是修改路线是一件十分麻烦的事情,会带来额外的成本。因此物流公司希望能够
    订一个n天的运输计划,使得总成本尽可能地小。
    Input
    第一行是四个整数n(1<=n<=100)、m(1<=m<=20)、K和e。
    n表示货物运输所需天数,m表示码头总数,K表示每次修改运输路线所需成本。
    接下来e行每行是一条航线描述,包括了三个整数,依次表示航线连接的两个码头编号以及航线长度(>0)。
    其中码头A编号为1,码头B编号为m。单位长度的运输费用为1。航线是双向的。再接下来一行是一个整数d,
    后面的d行每行是三个整数P( 1 < P < m)、a、b(1 < = a < = b < = n)。表示编号为P的码头从第a天
    到第b天无法装卸货物(含头尾)。同一个码头有可能在多个时间段内不可用。但任何时间都存在至少一条从码头A到码头B的运输路线。
    Output
    包括了一个整数表示最小的总成本。
    总成本=n天运输路线长度之和+K*改变运输路线的次数。
    Sample Input
    5 5 10 8
    
    1 2 1
    
    1 3 3
    
    1 4 2
    
    2 3 2
    
    2 4 4
    
    3 4 1
    
    3 5 2
    
    4 5 2
    
    4
    
    2 2 3
    
    3 1 1             
    
    3 3 3
    
    4 4 5
    
    Sample Output
    32
    HINT
    
    前三天走1-4-5,后两天走1-3-5,这样总成本为(2+2)*3+(3+2)*2+10=32 
    

    算法讨论:

    先用SPFA处理出第i到第j天内起点到终点的最短路,然后Dp求解即可。

    代码:

    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
     
    using namespace std;
    const int N = 100 + 5;
    const int M = 20 + 5;
    const int inf = 100000;
     
    int n, m, k, e, d, cnt;
    int dis[M], t[N][N], dp[N];
    int head[N], que[N * 10];
    bool vis[M], kill[M], flag[M][N];
     
    struct Edge {
      int from, to, next, dis;
    }edges[N * N];
     
    void insert(int from, int to, int dis) {
      ++ cnt;
      edges[cnt].from = from; edges[cnt].to = to; edges[cnt].dis = dis;
      edges[cnt].next = head[from]; head[from] = cnt;
    }
     
    int spfa(int a, int b) {
      int had = 1, til = 1;
      for(int i = 1; i <= m; ++ i) {
        dis[i] = inf; vis[i] = false;
        kill[i] = false;
      }
      for(int i = 1; i <= m; ++ i)
        for(int j = a; j <= b; ++ j)
          kill[i] |= flag[i][j];
      dis[1] = 0; vis[1] = true;
      que[had] = 1;
      while(had <= til) {
        int u = que[had];
        vis[u] = false;
        for(int i = head[u]; i; i = edges[i].next) {
          int v = edges[i].to;
          if(!kill[v] && dis[v] > dis[u] + edges[i].dis) {
            dis[v] = dis[u] + edges[i].dis;
            if(!vis[v]) {
              vis[v] = true;
              que[++ til] = v;
            }
          }
        }
        ++ had;
      }
      return dis[m];
    }
     
    int main() {
      int x, y, z;
      scanf("%d%d%d%d", &n, &m, &k, &e);
      for(int i = 1; i <= e; ++ i) {
        scanf("%d%d%d", &x, &y, &z);
        insert(x, y, z); insert(y, x, z);
      }
      scanf("%d", &d);
      for(int i = 1; i <= d; ++ i) {
        scanf("%d%d%d", &z, &x, &y);
        for(int j = x; j <= y; ++ j)
          flag[z][j] = true;
      }
      for(int i = 1; i <= n; ++ i)
        for(int j = i; j <= n; ++ j)
          t[i][j] = spfa(i, j);
      for(int i = 1; i <= n; ++ i) {
        dp[i] = t[1][i] * i;
        for(int j = 1; j < i; ++ j) {
          dp[i] = min(dp[i], dp[j] + k + t[j + 1][i] * (i - j));
        }
      }
      printf("%d
    ", dp[n]);
      return 0;
    }
    
  • 相关阅读:
    python播放音频文件
    安装pyaudio
    给 python工程 打包并上传 PyPI (The Python Package Index)
    python怎么import自己写的包
    pip源使用国内镜像
    Git和GitHub
    nginx的日志轮转
    ab接口压力测试工具
    nginx 性能优化
    https协议
  • 原文地址:https://www.cnblogs.com/sxprovence/p/5393881.html
Copyright © 2011-2022 走看看