[ZJOI2006]物流运输trans

Description

物流公司要把一批货物从码头A运到码头B。由于货物量比较大,需要 n天才能运完。货物运输过程中一般要转停好几个码头。物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪。由于各种因素的存 在,有的时候某个码头会无法装卸货物。这时候就必须修改运输路线,让货物能够按时到达目的地。但是修改路线是一件十分麻烦的事情,会带来额外的成本。因此 物流公司希望能够订一个n天的运输计划,使得总成本尽可能地小。

Input

第一行是四个整数n(1<=n<=100)、m(1& lt;=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的 运输路线。

Output

包括了一个整数表示最小的总成本。总成本=n天运输路线长度之和+K*改变运输路线的次数。

Sample Input

5 5 10 8
1 2 1
1 3 3
1 4 2
2 3 2
2 4 4
3 4 1
3 5 2
4 5 2
4
2 2 3
3 1 1
3 3 3
4 4 5

Sample Output

Sample Output
32

HINT

前三天走1-4-5,后两天走1-3-5,这样总成本为(2+2)*3+(3+2)*2+10=32

 

 

一开始自以为想到很好的一个方法,再想想还是不对。。。。

所以很猥琐的看了题解:

解法:spfa+DP

cost[i][j] 表示从 i 天到 j 天满足条件的源点到汇点的最短路径,用spfa搞定;

f[i] 表示从第一天到第 i 天最小花费;

DP公式:

f[0]=-k;

f[i]=min(f[i],f[j]+cost[j+1][j]*(i-j)+k);  (0<=j<i)

 

 

另外WA了几次,是因为有重边而且数据溢出 o(╯□╰)o

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<fstream>
  6 #define Edgsize 6000000
  7 #define Nodesize 2000000
  8 #define Maxint 100000000
  9 
 10 using namespace std;
 11 //ifstream cin("cin.in");
 12 
 13 int n,m,S,T;
 14 int to[Edgsize],next[Edgsize],weight[Edgsize],head[Nodesize],edgs=0;
 15 int dis[Nodesize];
 16 typedef struct {
 17         int num,d;
 18         }Heap;Heap heap[Nodesize],temp;
 19        
 20 int seat(int x,int y,int z){
 21     if(z==1) return (x-1)*(m-1)+y;
 22     else return (n-1)*(m-1)+(x-1)*(m-1)+y;
 23     }
 24 
 25 void Addedg(int u,int v,int d){
 26      edgs++;to[edgs]=v;next[edgs]=head[u];weight[edgs]=d;head[u]=edgs;
 27      edgs++;to[edgs]=u;next[edgs]=head[v];weight[edgs]=d;head[v]=edgs;
 28      }
 29 
 30 int ans=Maxint;
 31 void Init(){
 32      //cout<<" sdf";system("pause"); 
 33      cin>>n>>m;
 34      
 35      S=(n-1)*(m-1)*2+1;T=S+1;
 36      memset(head,-1,sizeof(head));
 37      
 38      int d;
 39      
 40      if(n==1||m==1)
 41      {
 42        for(int i=1;i<n||i<m;++i)
 43        {cin>>d;if(d<ans) ans=d;}return ;
 44                    }
 45      
 46      for(int i=1;i<=n;++i)
 47      for(int j=1;j<m;++j)
 48      {
 49        cin>>d;
 50        if(i==1) Addedg(S,seat(1,j,1),d);
 51        else if(i==n) Addedg(seat(i-1,j,2),T,d);
 52        else Addedg(seat(i-1,j,2),seat(i,j,1),d);
 53              }
 54      
 55      for(int i=1;i<n;++i)
 56      for(int j=1;j<=m;++j)
 57      {
 58        cin>>d;
 59        if(j==1) Addedg(seat(i,j,2),T,d);
 60        else if(j==m) Addedg(seat(i,j-1,1),S,d);
 61        else Addedg(seat(i,j-1,1),seat(i,j,2),d);
 62              }
 63      
 64      for(int i=1;i<n;++i)
 65      for(int j=1;j<m;++j)
 66      {
 67        cin>>d;
 68        Addedg(seat(i,j,1),seat(i,j,2),d);
 69              }
 70      
 71      }
 72      
 73      
 74 int len=1;
 75 void Down(int site){
 76      
 77      while(1)
 78      {//cout<<"down"<<endl;
 79        int least=site,left=2*site,right=2*site+1;
 80        if(left<=len&&heap[left].d<heap[least].d) least=left;
 81        if(right<=len&&heap[right].d<heap[least].d) least=right;
 82        
 83        if(least!=site)
 84        {
 85          swap(heap[site],heap[least]);
 86          site=least;  
 87                       }
 88        else break;
 89              
 90              }
 91      
 92      }
 93 
 94 void Up(int site){
 95      int f=site/2;
 96      while(f>0&&heap[site].d<heap[f].d)
 97      {
 98        swap(heap[site],heap[f]);
 99        site=f;
100        f/=2;   
101                }
102      }
103 
104 void Delete_min(int l){
105      if(l==0) return ;
106      swap(heap[1],heap[l+1]);
107      Down(1);
108      }
109 
110 
111 void Dijkstra(){
112      for(int i=1;i<=T;++i)
113      dis[i]=Maxint;
114      heap[1].num=S;heap[1].d=0;dis[S]=0;
115      
116      for(int i=1;i<=T&&len>0;++i)
117      {
118        temp=heap[1];
119        len--;  
120        Delete_min(len); //cout<<"  sdfg"<<endl; 
121        
122        for(int j=head[temp.num];j!=-1;j=next[j])
123        if(dis[to[j]]>dis[temp.num]+weight[j])
124        {
125          dis[to[j]]=dis[temp.num]+weight[j];
126          len++;//cout<<len<<"  "<<endl;
127          heap[len].num=to[j];heap[len].d=dis[to[j]];  
128          Up(len);
129                }   
130             // system("pause");
131              }
132      cout<<dis[T]<<endl;
133      }
134 
135 int main(){
136     Init();///cout<<n<<" "<<m<<endl;
137     if(ans!=Maxint) {cout<<ans<<endl;return 0;}
138     Dijkstra();
139     //system("pause");
140     return 0;
141     
142     }

 

posted on 2013-03-08 16:43  怡红公子  阅读(1028)  评论(0编辑  收藏  举报