[ZJOI2006]物流运输(最短路 + 区间dp)
题干:
物流公司要把一批货物从码头 A 运到码头 B。由于货物量比较大,需要 n 天才能运完。货物运输过程中一般要转停好几个码头。物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪。由于各种因素的存在,有的时候某个码头会无法装卸货物。这时候就必须修改运输线路,让货物能够按时到达目的地。但是修改路线是一件十分麻烦的事情,会带来额外的成本,因此物流公司希望能够订一个 n 天的运输计划,使得总成本尽可能地小。
第一行是四个整数 n(1≤n≤100),m(1≤m≤20),K,e。n 表示货物运输所需天数,m 表示码头总数,K 表示每次修改运输路线所需成本,接下来 e 行每行是一条航线描述,包括了三个整数,依次表示航线连接的两个码头编号以及航线长度 (>0)。其中码头 A 编号为 1,码头 B 编号为 m。单位长度的运输费用为 1。航线是双向的。再接下来一行是一个整数 d,后面的 d 行每行是三个整数 P(1<P<m),a,b(1≤a≤b≤n)。表示编号为 P 的码头从第 a 天到第 b 天无法装卸货物(含头尾)。同一个码头有可能在多个时间段内不可用。但任何时间都存在至少一条从码头 A 到码头 B 的运输路线。
包括了一个整数表示最小的总成本。总成本 = n 天运输路线长度之和 + K × 改变运输路线的次数。
题解:
先看一下题:本题让求出1~n天运输路线所花费的费用,表示一头雾水。。。题干中还给出,哪几个点在a~b区间范围内不可被使用,又一头雾。。。其实我们再回头看一下,1~n天的费用就是:
1、1~x天的第一种路线费用 + x+1天的第二种的路线费用 + 改变路线的费用
2、1~x天的第一种路线费用 + x+1天的第一种的路线费用 (其实这种就可以合并)。
这样分出情况来看,我们好像就可以设出状态转移方程:
dp[i][j]表示i~j天期间的最小路线费用(这就意味着后面所说的最短路均为从1~n的最短路,我们在此将每一天作为一个单位),那么:
dp[1]
=dp[1][x]+dp[x+1][y]+......+dp[z+1]
+ t*K
这不就是区间dp吗?有一股正解的气息。。。
我们来考虑一下初始化的问题(假设dp[i][j]):
1、i==j时,就是跑一个有不能经过的点的最短路的长度(权值为一嘛)。
2、i > j时,无解(既然跑最短路,返程肯定不需要)
3、i < j时,毕竟是初始化,我们就假设它在i~j一段时间内没有转变路线,那么凡是在i~j期间有节点不能用,那么这个节点就一定不可能存在于现在的最短路中。我们将那几个点不可用的点标记后再跑一个最短路即可。(注意结果要乘上时间长度(j-i+1))
我们为什么要将dp[i][j](i < j)初始化为没有转变路线的情况呢?其实这与我们后面的dp转移有关。后面的转移一定不会再考虑大片的具有相同路径的连续几天了,我们只会考虑在哪一天换一下路线使总花费变小。所以就需要在初始化时将这种可能成为答案的、大片的具有相同路径的连续几天的情况了。如果这i~j天不能用的港口太多,导致无解,那就让它无解吧,反正到后面合并时会更新,就不考虑这种情况了。
有了上面的初始化( Dijkstra 与 spfa 都可以),我们就来写一下区间dp的式子(其实跟普通区间dp没两样):
dp[i][j]=Σj-1q=imin(dp[i][j],dp[i][q]+dp[q+1][j]+k);
got it!
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #define $ 210 5 using namespace std; 6 int n,m,k,e,first[$],tot,d,dp[$][$],lu[$/5]; 7 bool judge[$][$/5],vis[$],pro[$]; 8 struct tr 7ff7 ee{ int to,next,w; }a[$*2]; 9 inline int min(int x,int y){ return x<y?x:y; } 10 inline void add(int x,int y,int w){ 11 a[++tot]=(tree){ y,first[x],w }; 12 first[x]=tot; 13 a[++tot]=(tree){ x,first[y],w }; 14 first[y]=tot; 15 } 16 inline int Dijkstra(int start,int done){ 17 priority_queue< pair<int,int> > q; 18 memset(vis,0,sizeof(vis)); 19 memset(lu,63,sizeof(lu)); 20 memset(pro,0,sizeof(pro)); 21 for(register int i=start;i<=done;++i) 22 for(register int j=1;j<=m;++j) if(judge[i][j]) pro[j]=1; 23 lu[1]=0; 24 q.push(make_pair(0,1)); 25 while(q.size()){ 26 int x=q.top().second; q.pop(); 27 if(vis[x]) continue; 28 vis[x]=1; 29 for(register int i=first[x];i;i=a[i].next){ 30 int to=a[i].to,w=a[i].w; 31 if(pro[to]) continue; 32 if(lu[to]>lu[x]+w){ 33 lu[to]=lu[x]+w; 34 q.push(make_pair(-lu[to],to)); 35 } 36 } 37 } 38 return lu[m]; 39 } 40 inline int spfa(int start,int done){ 41 queue<int> q; 42 memset(vis,0,sizeof(vis)); 43 memset(lu,63,sizeof(lu)); 44 memset(pro,0,sizeof(pro)); 45 for(register int i=start;i<=done;++i) 46 for(register int j=1;j<=m;++j) if(judge[i][j]) pro[j]=1; 47 q.push(1); lu[1]=0; 48 vis[1]=1; 49 while(q.size()){ 50 int x=q.front(); q.pop(); 51 vis[x]=0; 52 for(register int i=first[x];i;i=a[i].next){ 53 int to=a[i].to,w=a[i].w; 54 if(pro[to]) continue; 55 if(lu[to]>lu[x]+w){ 56 lu[to]=lu[x]+w; 57 if(!vis[to]) q.push(to),vis[to]=1; 58 } 59 } 60 } 61 return lu[m]; 62 } 63 signed main(){ 64 memset(dp,63,sizeof(dp)); 65 scanf("%d%d%d%d",&n,&m,&k,&e); 66 for(register int i=1,x,y,z;i<=e;++i) 67 scanf("%d%d%d",&x,&y,&z),add(x,y,z); 68 scanf("%d",&d); 69 for(register int i=1,x,l,r;i<=d;++i){ 70 scanf("%d%d%d",&x,&l,&r); 71 for(register int j=l;j<=r;++j) judge[j][x]=1; 72 } 73 for(register int i=1;i<=n;++i) 74 for(register int j=i,x;j<=n;++j){ 75 x=i%2?Dijkstra(i,j):spfa(i,j); 76 if(x<100000) dp[i][j]=x*(j-i+1); 77 else dp[i][j]=0x7ffffff; 78 } 79 for(register int l=2;l<=n;++l){ 80 for(register int i=1;i<=n-l+1;++i){ 81 int j=i+l-1; 82 for(register int q=i;q<j;++q) 83 dp[i][j]=min(dp[i][j],dp[i][q]+dp[q+1][j]+k); 84 } 85 } 86 printf("%d\n",dp[1] ); 87 }View Code
转载于:https://www.cnblogs.com/OI-zzyy/p/11177941.html
- [BZOJ1003][ZJOI2006]物流运输(最短路+dp)
- 最短路+DP [ZJOI2006]物流运输
- 【BZOJ1003】[ZJOI2006]物流运输trans【最短路】【DP】
- [ZJOI2006]物流运输 (最短路+dp)
- [BZOJ1003][ZJOI2006]物流运输(最短路+DP)
- bzoj1003: [ZJOI2006]物流运输(最短路+Dp)
- BZOJ.1003.[ZJOI2006]物流运输(DP 最短路Dijkstra)
- BZOJ 1003: [ZJOI2006]物流运输trans(最短路+dp)
- BZOJ 1003 [ZJOI2006]物流运输(最短路+dp)
- [BZOJ1003][ZJOI2006]物流运输(最短路+dp)
- 【bzoj1003】【ZJOI2006】【物流运输】【最短路+dp】
- [bzoj1003][ZJOI2006][物流运输] (最短路+dp)
- 【bzoj1003】【ZJOI2006】【物流运输】【dp+最短路】
- [ZJOI2006] 物流运输trans (最短路dijkstra+dp)
- [ZJOI2006]物流运输trans dp 最短路
- bzoj 1003 [ZJOI2006]物流运输(最短路spfa+dp)
- bzoj1003: [ZJOI2006]物流运输trans[最短路+DP]
- bzoj1003 [ZJOI2006]物流运输(最短路+dp)
- 【BZOJ】【P1003】【ZJOI2006】【物流运输trans】【题解】【最短路+DP】
- 1003: [ZJOI2006]物流运输 最短路+dp