BZOJ 1003, 物流运输

5 篇文章 0 订阅
3 篇文章 0 订阅

Problem

传送门

Mean

参见题目描述。

Analysis

动态规划+最短路。
状态转移方程为f[i]=min(f[j-1]+d[m]*(i-j+1)+k),1≤j≤i≤n。d[m]为每次状态转移计算所得当前可行的最短路花费。

Code

#include<cstdio>
#include<utility>
#include<vector>
#include<queue>
using namespace std;
typedef pair<int,int> P;
const int D=2005,N=25,M=405,INF=~0U>>8;
int n,m,k,e,d,ed,x,y,z,f[105],v[M],w[M],nxt[M],g[N],p[D],l[D],r[D],c[N];
priority_queue<P,vector<P>,greater<P> > Q;
int min(int a,int b){return a<b?a:b;}
void addedge(int x,int y,int z){
    v[++ed]=y,w[ed]=z;
    nxt[ed]=g[x];
    g[x]=ed;
}
void dij(int x,int y){
    bool enable[N];
    for(int i=1;i<=m;i++) enable[i]=1;
    for(int i=0;i<d;i++) if(!(x>r[i] || y<l[i])) enable[p[i]]=0;
    for(int i=2;i<=m;i++) c[i]=INF;Q.push(P(c[1]=0,1));
    while(!Q.empty()){
        P t=Q.top();Q.pop();
        if(c[x=t.second]<t.first) continue;
        for(int i=g[x];i;i=nxt[i]) if(enable[v[i]] && c[x]+w[i]<c[v[i]]) Q.push(P(c[v[i]]=c[x]+w[i],v[i]));
    }
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&e);
    for(int i=0;i<e;i++){
        scanf("%d%d%d",&x,&y,&z);
        addedge(x,y,z),addedge(y,x,z);
    }
    scanf("%d",&d);
    for(int i=0;i<d;i++) scanf("%d%d%d",&p[i],&l[i],&r[i]);
    for(int i=1;i<=n;i++) f[i]=INF;f[0]=-k;
    for(int i=1;i<=n;i++) for(int j=1;j<=i;j++){
        dij(j,i);
        f[i]=min(f[i],f[j-1]+c[m]*(i-j+1)+k);
    }
    printf("%d",f[n]);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值