bzoj1003 [ZJOI2006]物流运输(spfa+dp)

来源:互联网 发布:手机应用隐藏软件 编辑:程序博客网 时间:2024/06/05 10:25

dp[i]=min{dp[j]+w[j+1][i]+K |1<=j< i}.w[i][j]表示i~j天不改变航线的最短路,用spfa求出。

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#define ll long long#define N 21#define M 200#define inf 0x3f3f3f3finline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();    return x*f;}int n,m,K,e,h[N],num=0,d[N],w[105][105];ll dp[105];bool broke[N][105],exist[N],f[N];struct edge{    int to,next,v;}data[M<<1];int spfa(int s,int t){    memset(f,0,sizeof(f));memset(d,0x3f,sizeof(d));    for(int i=1;i<=m;++i) exist[i]=1;    for(int i=1;i<=m;++i)        for(int j=s;j<=t;++j)            if(broke[i][j]) exist[i]=0;    std::queue<int>q;    q.push(1);f[1]=1;d[1]=0;    while(!q.empty()){        int x=q.front();q.pop();f[x]=0;        for(int i=h[x];i;i=data[i].next){            int y=data[i].to;            if(!exist[y]) continue;            if(d[x]+data[i].v<d[y]){                d[y]=d[x]+data[i].v;                if(!f[y]) q.push(y),f[y]=1;            }        }    }    return d[m];}int main(){//  freopen("a.in","r",stdin);    n=read();m=read();K=read();e=read();    while(e--){        int x=read(),y=read(),v=read();        data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].v=v;        data[++num].to=x;data[num].next=h[y];h[y]=num;data[num].v=v;    }    e=read();    while(e--){        int x=read(),s=read(),t=read();        for(int i=s;i<=t;++i) broke[x][i]=1;    }    for(int i=1;i<=n;++i)        for(int j=i;j<=n;++j) w[i][j]=spfa(i,j);//i~j天不改变航线的最短路     for(int i=1;i<=n;++i){        dp[i]=(ll)w[1][i]*i;        for(int j=1;j<i;++j) dp[i]=std::min(dp[i],dp[j]+K+(ll)w[j+1][i]*(i-j));    }    printf("%lld\n",dp[n]);    return 0;}
原创粉丝点击