• 【网络流24题】1745: 餐巾计划问题


    一个餐厅在相继的N 天里,每天需用的餐巾数不尽相同。假设第i天需要ri块餐巾(i=1, 2,…,N)。餐厅可以购买新的餐巾,每块餐巾的费用为p分;或者把旧餐巾送到快洗部, 洗一块需m天,其费用为f 分;或者送到慢洗部,洗一块需n 天(n>m),其费用为s< f 分。 每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多 少块保存起来延期送洗。但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。 试设计一个算法为餐厅合理地安排好N 天中餐巾使用计划,使总的花费最小。 编程任务: 编程找出一个最佳餐巾使用计划.
    由文件input.txt提供输入数据。文件第1 行有6 个正整数N,p,m,f,n,s。N 是要安排餐巾 使用计划的天数;p 是每块新餐巾的费用;m 是快洗部洗一块餐巾需用天数;f 是快洗部洗 一块餐巾需要的费用;n是慢洗部洗一块餐巾需用天数;s是慢洗部洗一块餐巾需要的费用。 接下来的N 行是餐厅在相继的N 天里,每天需用的餐巾数。
    程序运行结束时,将餐厅在相继的N 天里使用餐巾的最小总花费输出到文件output.txt 中。

    Sample Input

    3 10 2 3 3 2 5 6 7
    Sample Output
    145
     
    此题困扰我很久,发个题解来总结:
    刚开始在想怎么做到既流满当天的流又流到其他天去。设n为总天数,然后(s,i,inf,p)(i,i+n,ri,0)(i,i+n+m,INF,f)(i+n,T,INF,0)发现跑spfa会跑错答案
    然后就随之想到题解的做法:
    (s,i+n,ri,p)这是购买当天的
    (s,i,ri,0)(i,i+n+m,INF,f)(i,i+n+sn,INF,s)这是模拟送去快洗部和满洗部
    注意洗完后的餐巾不一定就要送到i+n+m,大于等于i+n+m皆可,所以连边(i,i+1,INF,0).表示洗完的餐巾当天不用,流向下一天 (傻逼的我居然把i到>=n+m+i的都建了边,然后TLE了)
    (i+n,T,ri,0)相当于限制当天的总餐具数
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 const int N=2005,INF=1999999999;
     8 int gi(){
     9     int str=0;char ch=getchar();
    10     while(ch>'9' || ch<'0')ch=getchar();
    11     while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar();
    12     return str;
    13 }
    14 int n,s,sn,p,F,fn,T,S=0,ans=0;
    15 int num=1,head[N],f[N],vis[N],q[N*10],pre[N];
    16 struct Lin{
    17     int next,to,dis,cost;
    18 }a[1000001];
    19 void init(int x,int y,int z,int cost){
    20     a[++num].next=head[x];
    21     a[num].to=y;
    22     a[num].dis=z;
    23     a[num].cost=cost;
    24     head[x]=num;
    25     a[++num].next=head[y];
    26     a[num].to=x;
    27     a[num].dis=0;
    28     a[num].cost=-cost;
    29     head[y]=num;
    30 }
    31 void Change()
    32 {
    33     int x=T,flow=INF;
    34     while(x){
    35         flow=min(flow,a[pre[x]].dis);
    36         x=a[pre[x]^1].to;
    37     }
    38     x=T;
    39     while(x){
    40         a[pre[x]].dis-=flow;
    41         a[pre[x]^1].dis+=flow;
    42         ans+=a[pre[x]].cost*flow;
    43         x=a[pre[x]^1].to;
    44     }
    45 }
    46 bool spfa()
    47 {
    48     for(int i=0;i<=T;i++)f[i]=INF,vis[i]=false;
    49     int t=0,sum=1,x,u;
    50     q[1]=S;f[S]=0;vis[S]=true;
    51     while(t!=sum)
    52     {
    53         x=q[++t];
    54         for(int i=head[x];i;i=a[i].next)
    55         {
    56             if(a[i].dis<=0)continue;
    57             u=a[i].to;
    58             if(f[x]+a[i].cost<f[u])
    59             {
    60                 f[u]=f[x]+a[i].cost;
    61                 pre[u]=i;
    62                 if(!vis[u])vis[u]=true,q[++sum]=u;
    63             }
    64         }
    65         vis[x]=false;
    66     }
    67     return f[T]!=INF;
    68 }
    69 int main()
    70 {
    71     //freopen("pp.in","r",stdin);
    72     int x;
    73     n=gi();p=gi();fn=gi();F=gi();sn=gi();s=gi();T=(n<<1)+1;
    74     for(int i=1;i<=n;i++){
    75         x=gi();
    76         init(S,i,x,0);
    77         init(i+n,T,x,0);
    78         init(S,i+n,x,p);
    79         if(i<n)init(i,i+1,INF,0);
    80         if(i+fn<=n)init(i,i+n+fn,INF,F);
    81         if(i+sn<=n)init(i,i+n+sn,INF,s);
    82     }
    83     while(spfa())Change();
    84     printf("%d",ans);
    85     return 0;
    86 }
  • 相关阅读:
    ST的电机开发硬件套件NUCLEO-G431RB和X-NUCLEO-IHM16M1
    计算机软件世界的思维方式
    vue 动态路由配置,路由由后台返回
    element Cascader组件通过最后一级ID查找匹配的父级ID
    git push本地代码成功,远程提交未更新
    面试整理之原理问题
    JS执行环境与作用域理解
    webpack原理类型问题
    __webpack_require__(...) is not a function
    express+cors模拟解决跨域
  • 原文地址:https://www.cnblogs.com/Yuzao/p/6883601.html
Copyright © 2020-2023  润新知