BZOJ1003: [ZJOI2006]物流运输

1003: [ZJOI2006]物流运输

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 8800  Solved: 3747
[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
//前三天走1-4-5,后两天走1-3-5,这样总成本为(2+2)*3+(3+2)*2+10=32

HINT

 

Source

 

【题解】

预处理ans[i][j]表示第i天到第j天(或第j天到第i天)全部走某一条路径的最短路

dp即可

dp[i]表示1..i天的最短花费

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <vector>
  8 #define min(a, b) ((a) < (b) ? (a) : (b))
  9 #define max(a, b) ((a) > (b) ? (a) :(b))
 10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
 11 
 12 inline void read(int &x)
 13 {
 14     x = 0;char ch = getchar(), c = ch;
 15     while(ch < '0' || ch > '9') c = ch, ch = getchar();
 16     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
 17     if(c == '-') x = -x;
 18 }
 19 
 20 const int MAXN = 20 + 10;
 21 const int MAXM = 10000 + 5;
 22 const int MAXT = 100 + 10;
 23 const int INF = 0x3f3f3f3f;
 24 
 25 struct Edge
 26 {
 27     int u, v, w, nxt;
 28     Edge(int _u, int _v, int _w, int _nxt){u = _u;v = _v;nxt = _nxt;w = _w;}
 29     Edge(){}
 30 }edge[MAXM << 1];
 31 int head[MAXN], cnt, bb[MAXN];
 32 inline void insert(int a, int b, int c)
 33 {
 34     edge[++cnt] = Edge(a, b, c, head[a]);
 35     head[a] = cnt;
 36 }
 37 
 38 int n,m,val,t,tmp,a1[10000],a2[10000],a3[10000];
 39 
 40 int d[MAXN], b[MAXN], ans[MAXT][MAXT];
 41 
 42 struct Node
 43 {
 44     int v,w;
 45     Node(int _v, int _w){v = _v;w = _w;}
 46     Node(){}
 47 };
 48 
 49 struct cmp
 50 {
 51     bool operator()(Node a, Node b)
 52     {
 53         return a.w > b.w;
 54     }
 55 };
 56 
 57 std::priority_queue<Node, std::vector<Node>, cmp> q;
 58 
 59 void dij()
 60 {
 61     memset(b, 0, sizeof(b));
 62     memset(d, 0x3f, sizeof(b));
 63     d[1] = 0;
 64     q.push(Node(1, 0));
 65     while(q.size())
 66     {
 67         Node now = q.top();
 68         q.pop();
 69         if(b[now.v]) continue;
 70         b[now.v] = 1;
 71         for(register int pos = head[now.v];pos;pos = edge[pos].nxt)
 72         {
 73             int v = edge[pos].v;
 74             if(bb[v]) continue;
 75             if(d[v] > d[now.v] + edge[pos].w)
 76             {
 77                 d[v] = d[now.v] + edge[pos].w;
 78                 if(!b[v]) q.push(Node(v, d[v]));
 79             }
 80         }
 81     }
 82 }
 83 
 84 int dp[10000];
 85 
 86 int main()
 87 {
 88     read(t), read(n), read(val), read(m);
 89     for(register int i = 1;i <= m;++ i)
 90     {
 91         int tmp1,tmp2,tmp3;
 92         read(tmp1), read(tmp2), read(tmp3);
 93         insert(tmp1, tmp2, tmp3);
 94         insert(tmp2, tmp1, tmp3);
 95     }
 96     read(tmp);
 97     for(register int i = 1;i <= tmp;++ i)
 98         read(a3[i]), read(a1[i]), read(a2[i]);
 99     for(register int i = 1;i <= t;++ i)
100         for(register int j = i;j <= t;++ j)
101         {
102             memset(bb, 0, sizeof(bb));
103             for(register int k = 1;k <= tmp;++ k)
104                 if(a1[k] <= j && a2[k] >= i)
105                     bb[a3[k]] = 1;
106             dij();
107             if(d[n] != INF)    ans[i][j] = ans[j][i] = d[n] * (j - i + 1);
108             else ans[i][j] = ans[j][i] = INF;
109         }
110     for(register int i = 1;i <= t;++ i)
111     {
112         dp[i] = ans[1][i];
113         for(register int j = 1;j < i;++ j)
114             dp[i] = min(dp[i], dp[j] + ans[i][j + 1] + val);
115     }
116     printf("%d", dp[t]);
117     return 0;
118 } 
BZOJ1003

 

posted @ 2017-12-03 23:34  嘒彼小星  阅读(198)  评论(0编辑  收藏  举报