1003: [ZJOI2006]物流运输trans

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求出任意一段时间起点到终点的最短路,
然后再进行DP即可
 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<algorithm>
 7 #include<string>
 8 #include<map>
 9 #include<queue>
10 #include<vector>
11 #include<set>
12 #define inf 1000000000
13 #define maxn 25
14 #define maxm 105
15 #define eps 1e-10
16 #define ll long long
17 #define for0(i,n) for(int i=0;i<(n);i++)
18 #define for1(i,n) for(int i=1;i<=(n);i++)
19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
22 using namespace std;
23 int read(){
24     int x=0,f=1;char ch=getchar();
25     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
26     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
27     return x*f;
28 }
29 struct data{
30     int go,next,w;
31 }e[805];
32 int tot,head[maxn],n,m,k;
33 bool flag[maxm][maxn];
34 ll t[maxm][maxm],f[maxm];
35 void insert(int x,int y,int z){
36     e[++tot].go=y;e[tot].next=head[x];head[x]=tot;e[tot].w=z;
37 }
38 void ins(int x,int y,int z){
39     insert(x,y,z);insert(y,x,z);
40 }
41 int spfa(int a,int b){
42     bool book[maxn];
43     int d[maxn],q[500],inq[maxn];
44     memset(book,0,sizeof(book));
45     memset(d,0x3f,sizeof(d));
46     memset(inq,0,sizeof(inq));
47     for(int i=a;i<=b;i++)
48         for(int j=1;j<=m;j++)
49             if(flag[i][j])book[j]=1;
50     q[0]=1;inq[1]=1;d[1]=0;
51     int t=0,w=1;
52     while(t<w){
53         for(int i=head[q[t]],y;i;i=e[i].next){
54             if(!book[y=e[i].go]&&d[y]>d[q[t]]+e[i].w){
55                 d[y]=d[q[t]]+e[i].w;
56                 if(!inq[y]){q[w++]=y;inq[y]=1;}
57             }
58         }
59         inq[q[t++]]=0;
60     }
61     return d[m];
62 }
63 int main(){
64     //freopen("input.txt","r",stdin);
65     //freopen("output.txt","w",stdout);
66     int q;n=read(),m=read(),k=read(),q=read();
67     for1(i,q){
68         int x=read(),y=read(),z=read();
69         ins(x,y,z);
70     }
71     int d=read();
72     for1(i,d){
73         int x=read(),y=read(),z=read();
74         for2(j,y,z)flag[j][x]=1; 
75     }
76     for1(i,n)
77         for1(j,n)
78             t[i][j]=spfa(i,j);
79     for1(i,n){
80         f[i]=(ll)t[1][i]*i;
81         for0(j,i)
82             f[i]=min(f[i],f[j]+k+t[j+1][i]*(i-j));
83     }
84     printf("%lld",f[n]);
85     return 0;
86 }
View Code

 

posted @ 2016-04-03 23:08  HTWX  阅读(125)  评论(0编辑  收藏  举报