物流公司要把一批貨物從碼頭A運到碼頭B。因爲貨物量比較大,須要n天才能運完。貨物運輸過程當中通常要轉停好幾個碼頭。物流公司一般會設計一條固定的運輸路線,以便對整個運輸過程實施嚴格的管理和跟蹤。因爲各類因素的存在,有的時候某個碼頭會沒法裝卸貨物。這時候就必須修改運輸路線,讓貨物可以按時到達目的地。可是修改路線是—件十分麻煩的事情,會帶來額外的成本。所以物流公司但願可以訂一個n天的運輸計劃,使得總成本儘量地小。ios
咱們令f[i]表示到第i天所須要的花費,咱們假設第j天到第i天的線路同樣,第j天和第j-1天不同那麼咱們能得出方程:git
f[i]=min(f[i],f[j]+(i-j+1)*cost+K)spa
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; }