zoukankan      html  css  js  c++  java
  • [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     }
  • 相关阅读:
    页面监控容器实现记录
    负载均衡基础理论
    asp.net部署时加密config文件
    还原bak到localdb的问题:The logical database file cannot be found ldf
    Could not load file or assembly 'System.Data.SQLite ... 试图加载格式不正确的程序
    Window vista 以上制作自定义证书并为端口配置ssl
    1-6、算法设计常用思想之迭代法
    1-5、算法设计常用思想之穷举法
    1-4、算法设计常用思想之动态规划法
    游戏开发-cocos creator踩坑-bind(this)导致的事件监听off不掉
  • 原文地址:https://www.cnblogs.com/noip/p/2950215.html
Copyright © 2011-2022 走看看