bzoj1003/luogu1772 物流运输 (dijkstra+dp)
先求出某一段时间[i,j]一直用同一个路径的最短路,乘上天数,记作cost[i,j]
那就可以设f[i]是前i天的最小代价,f[i]=f[j]+cost[j+1,i]+K
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define ll long long 4 using namespace std; 5 const int maxn=110,maxm=25; 6 7 ll rd(){ 8 ll x=0;char c=getchar();int neg=1; 9 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 10 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 11 return x*neg; 12 } 13 14 struct Edge{ 15 int a,b,l,ne; 16 }eg[maxm*maxm*2]; 17 int N,M,K,E,D,egh[maxm],ect; 18 int di[maxm][maxn],dis[maxm],mi[maxm],cost[maxn][maxn]; 19 int f[maxn]; 20 bool can[maxm][maxn],used[maxm],flag[maxm]; 21 22 inline void adeg(int a,int b,int l){ 23 eg[++ect].a=a;eg[ect].b=b;eg[ect].l=l;eg[ect].ne=egh[a];egh[a]=ect; 24 } 25 26 inline int dijkstra(){ 27 priority_queue<pa,vector<pa>,greater<pa> > q;while(!q.empty()) q.pop(); 28 memset(dis,127,sizeof(dis));memset(flag,0,sizeof(flag)); 29 dis[1]=0;q.push(make_pair(0,1)); 30 while(!q.empty()){ 31 int p=q.top().second;q.pop();if(flag[p]||!used[p]) continue; 32 if(p==M) break; 33 for(int i=egh[p];i!=-1;i=eg[i].ne){ 34 int b=eg[i].b; 35 if(dis[b]>dis[p]+eg[i].l){ 36 dis[b]=dis[p]+eg[i].l; 37 q.push(make_pair(dis[b],b)); 38 } 39 }flag[p]=1; 40 }return dis[M]; 41 } 42 43 inline void pre(){ 44 for(int i=1;i<=N;i++){ 45 memset(mi,127,sizeof(mi)); 46 for(int j=i;j<=N;j++){memset(used,0,sizeof(used)); 47 used[1]=used[M]=1; 48 for(int k=2;k<M;k++){ 49 mi[k]=min(mi[k],(int)can[k][j]); 50 if(mi[k]) used[k]=1; 51 }int re=dijkstra(); 52 cost[i][j]=(re>=0x3f3f3f3f)?-1:re*(j-i+1); 53 //printf("%d %d %d\n",i,j,cost[i][j]); 54 } 55 } 56 } 57 58 int main(){ 59 int i,j,k; 60 N=rd(),M=rd(),K=rd(),E=rd(); 61 memset(egh,-1,sizeof(egh)); 62 for(i=1;i<=E;i++){ 63 int a=rd(),b=rd(),c=rd(); 64 adeg(a,b,c);adeg(b,a,c); 65 }D=rd(); 66 for(i=1;i<=D;i++){ 67 int a=rd(),b=rd(),c=rd(); 68 di[a][b]=1;di[a][c+1]=-1; 69 }for(i=1;i<=M;i++){ 70 for(j=1,k=0;j<=N;j++){ 71 k+=di[i][j];can[i][j]=k?0:1; 72 } 73 }pre();memset(f,127,sizeof(f));f[0]=-K; 74 for(i=1;i<=N;i++){ 75 for(j=0;j<i;j++){ 76 if(cost[j+1][i]==-1) continue; 77 f[i]=min(f[j]+cost[j+1][i]+K,f[i]); 78 }//printf("%d %d\n",i,f[i]); 79 }printf("%d\n",f[N]); 80 return 0; 81 }