bzoj1003 物流运输

题目描述

物流公司要把一批货物从码头A运到码头B。由于货物量比较大,需要n天才能运完。货物运输过程中一般要转停好几个码头。物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪。由于各种因素的存在,有的时候某个码头会无法装卸货物。这时候就必须修改运输路线,让货物能够按时到达目的地。但是修改路线是—件十分麻烦的事情,会带来额外的成本。因此物流公司希望能够订一个n天的运输计划,使得总成本尽可能地小。

 

我们令f[i]表示到第i天所需要的花费,我们假设第j天到第i天的线路一样,第j天和第j-1天不一样那么我们能得出方程:

f[i]=min(f[i],f[j]+(i-j+1)*cost+K)

cost用Dijkstra求就可以了,但是注意,要标记未开通的边不能走。

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <cstring>
#define in(a) a=read()
#define REP(i,k,n)  for(int i=k;i<=n;i++) 
#define MAXN 2005 
using namespace std;
inline int read(){
    int x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar())
        if(ch=='-')
            f=-1;
    for(;isdigit(ch);ch=getchar())
        x=x*10+ch-'0';
    return x*f;
} 
//queue <int> Q;
typedef pair<int,int> P;
int n,m,K,e,d;
int total,head[MAXN],to[MAXN<<1],nxt[MAXN<<1],val[MAXN<<1];
int f[MAXN],book[MAXN][MAXN],ban[MAXN],dis[MAXN],vis[MAXN]; 
priority_queue<P, vector<P>,greater<P> > Q; 
inline void adl(int a,int b,int c){
    total++;
    to[total]=b;
    val[total]=c;
    nxt[total]=head[a];
    head[a]=total;
    return ;
} inline int Dijkstra(){
    memset(dis,127,sizeof(dis)); 
    dis[1]=0;
    Q.push(P(0,1));
    while(!Q.empty()){
        int u=Q.top().second;Q.pop(); 
        if(vis[u])  continue;
        vis[u]=0;
        for(int e=head[u];e;e=nxt[e])
            if(dis[to[e]]>dis[u]+val[e] && !ban[to[e]]){
                dis[to[e]]=dis[u]+val[e];
                Q.push(P(dis[to[e]],to[e]));
            }
    }
    return dis[m];
}
int main(){
    int a,b,c; 
    in(n),in(m),in(K),in(e);
    REP(i,1,e)  in(a),in(b),in(c),adl(a,b,c),adl(b,a,c);
    in(d);
    REP(i,1,d){
        in(a),in(b),in(c);
        REP(j,b,c)  book[a][j]=1;
    }
    memset(f,127,sizeof(f));
    f[0]=-K;
    REP(i,1,n){
        REP(j,1,m)  ban[j]=0;
        for(int j=i;j>=1;j--){
            REP(k,1,m)  if(book[k][j])  ban[k]=1;
            int sum=Dijkstra();
            if(sum>=100000000)  break;
            f[i]=min(f[i],f[j-1]+(i-j+1)*sum+K);
        }
    }
    cout<<f[n];
    return 0; 
} 

 

posted @ 2019-01-30 09:49  Dijkstra·Liu  阅读(363)  评论(0编辑  收藏  举报