• [ZJOI2006]物流运输 瞎跑spfa+瞎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*改变运输路线的次数。

    solution

    这个题真的是瞎跑就行

    先预处理出cost[i][j] 从i天到j天不换路的最短路费用 、road[i][j] 从第i天到第j天路径 (二进制存储)

    f[i]表示前i天的最小费用  g[i]表示前i天最后一次换的路径

    f[i]=min(f[j]+cost[j+1][i]+ (g[j]==road[j+1][i]?0:k) )  (0<=j<i) 

    f[0]=-k

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<queue>
      5 #define mem(a,b) memset(a,b,sizeof(a))
      6 using namespace std;
      7 struct son
      8 {
      9     int v,next,w;
     10 };
     11 son a1[10006];
     12 int first[10006],e;
     13 void addbian(int u,int v,int w)
     14 {
     15     a1[e].w=w;
     16     a1[e].v=v;
     17     a1[e].next=first[u];
     18     first[u]=e++;
     19 }
     20 
     21 int n,m,k,num;
     22 int u,o,p,l;
     23 int ji[106][26],flag[26][106][106];
     24 int cost[106][106],lu[106][106];
     25 int f[106],g[106];
     26 
     27 queue<int> q;
     28 int d[26],r[26],vis[26];
     29 void spfa(int o,int p)
     30 {
     31     mem(vis,0);mem(d,1);mem(r,0);
     32     d[1]=0;r[1]|=1;vis[1]=1;q.push(1);
     33     while(!q.empty())
     34     {
     35         int now=q.front();q.pop();vis[now]=0;
     36         for(int i=first[now];i!=-1;i=a1[i].next)
     37         {
     38             int temp=a1[i].v;
     39             if(flag[temp][o][p])continue;
     40             if(d[temp]>d[now]+a1[i].w)
     41             {
     42                 d[temp]=d[now]+a1[i].w;
     43                 r[temp]=r[now]|(1<<(temp-1));
     44                 if(!vis[temp])
     45                 {
     46                     q.push(temp);
     47                     vis[temp]=1;
     48                 }
     49             }
     50         }
     51     }
     52 }
     53 
     54 void SPFA()
     55 {
     56     for(int i=1;i<=n;++i)
     57       for(int j=i;j<=n;++j)
     58       {
     59         spfa(i,j);
     60         cost[i][j]=d[m]*(j-i+1);
     61         lu[i][j]=r[m];
     62         }
     63 }
     64 
     65 void out11()
     66 {
     67     printf("
    ");
     68     for(int i=1;i<=n;++i)
     69       printf("i=%d f[i]=%d
    ",i,f[i]);
     70     /*for(int i=1;i<=n;++i)
     71     {
     72         for(int j=1;j<=n;++j)
     73             printf("%d ",cost[i][j]);
     74         printf("
    ");
     75     }
     76     printf("
    ");
     77     for(int i=1;i<=n;++i)
     78     {
     79         for(int j=1;j<=n;++j)
     80             printf("%d ",lu[i][j]);
     81         printf("
    ");
     82     }*/
     83     printf("
    ");
     84 }
     85 
     86 int main(){
     87     
     88     //freopen("1.txt","r",stdin);
     89     
     90     //freopen("bzoj_1003.in","r",stdin);
     91     //freopen("bzoj_1003.out","w",stdout);
     92     
     93     mem(first,-1);
     94     
     95     scanf("%d%d%d%d",&n,&m,&k,&num);
     96     for(int i=1;i<=num;++i)
     97     {
     98         scanf("%d%d%d",&u,&o,&p);
     99         addbian(u,o,p);
    100         addbian(o,u,p);
    101     }
    102     scanf("%d",&l);
    103     for(int i=1;i<=l;++i)
    104     {
    105         scanf("%d%d%d",&u,&o,&p);
    106         for(int j=o;j<=p;++j)
    107           ji[j][u]=1;
    108     }
    109     for(int pp=1;pp<=m;++pp)
    110         for(int i=1;i<=n;++i)
    111         {
    112             int temp=0;
    113           for(int j=i;j<=n;++j)
    114           {
    115                 if(ji[j][pp])
    116                   temp=1;
    117                 flag[pp][i][j]=temp;
    118             }
    119         }
    120     
    121     SPFA();
    122     
    123     //out11();
    124     
    125     mem(f,1);
    126     g[0]=0;
    127     f[0]=-k;
    128     for(int i=1;i<=n;++i)
    129         for(int j=0;j<i;++j)
    130           if(f[i]>f[j]+cost[j+1][i]+(g[j]==lu[j+1][i]?0:k))
    131           {
    132                 f[i]=f[j]+cost[j+1][i]+(g[j]==lu[j+1][i]?0:k);
    133                 g[i]=lu[j+1][i];
    134             }
    135     //out11();
    136     cout<<f[n];
    137     //while(1);
    138     return 0;
    139 }
    code
  • 相关阅读:
    《C++ 并发编程》- 第1章 你好,C++的并发世界
    30分钟,让你成为一个更好的程序员
    程序员技术练级攻略
    谈新技术学习方法-如何学习一门新技术新编程语言
    计算机科学中最重要的32个算法
    程序员学习能力提升三要素
    一位在MIT教数学的老师总结了十条经验
    学习算法之路
    十个顶级的C语言资源助你成为优秀的程序员
    Linux中LoadAverage分析
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7358134.html
Copyright © 2020-2023  润新知