• 题解 【中学高级本-网络流24题】餐巾计划


    【中学高级本-网络流24题】餐巾计划

    Description

    一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N)。餐厅可以从三种途径获得餐巾。
    (1)购买新的餐巾,每块需p分;
    (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f<p)。如m=l时,第一天送到快洗部的餐巾第二天就可以使用了,送慢洗的情况也如此。
    (3)把餐巾送到慢洗部,洗一块需n天(n>m),费用需s分(s<f)。
    在每天结束时,餐厅必须决定多少块用过的餐巾送到快洗部,多少块送慢洗部。在每天开始时,餐厅必须决定是否购买新餐巾及多少,使洗好的和新购的餐巾之和满足当天的需求量Ri,并使N天总的费用最小。

    Input

    共 3 行:
    第 1 行为总天教;
    第 2 行为每天所需的餐巾块数;
    第 3 行为每块餐巾的新购费用 p ,快洗所需天数 m ,快洗所需费用 f ,慢洗所需天数 n ,慢洗所需费用 s 。

    Output

    一行,最小的费用

    Sample Input

    3
    3 2 4
    10 1 6 2 3

    Sample Output

    64

    Hint

    数据规模:
    n<=200,Ri<=50

    Source

    网络流
    线性规划网络优化,最小费用最大流

     
     

    解析

    这题也就是建图。。。

    首先,我们要考虑拆点,

    将一天拆成早上和晚上,

    那么,每天早上,餐厅都会得到到干净的餐巾,

    而餐巾则来自于购买,或是kt,mt天前的晚上(因为洗完了)(本题解中,kt为快洗天数,mt为慢洗天数,kp为快洗价格,mp为慢洗价格)。

    而每天晚上,餐厅都将有X张旧餐巾产生,

    而这些餐巾将会被快洗,慢洗,扔掉或是留到后一天晚上(第一次交的时候没考虑这种情况然后WA了)。

    那么,我们就可以开始建图了!

    首先,将源点与每天晚上连起来,流量为当天需要的餐巾数,费用为零,表示当天晚上收到的旧餐巾。

    接下来,将每天晚上与kt,mt天后的早上连起来(大于n要特判),

    流量为INF,费用为kp,mp,

    表示洗完后的早上能得到洗的餐巾。

    再将每天晚上与后一天晚上连起来,流量为INF,费用为零,表示将当天的旧餐巾放到第二天晚上再处理。

    最后,将每天早上与汇点连起来,流量为当天的餐巾数,费用为零,表示当天早上收到的餐巾。

    再跑最小费用最大流就行了!

    上AC代码:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    inline ll read(){
        ll sum=0,f=1;char ch=getchar();
        while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
        return f*sum;
    }
    
    const int INF=10000000000000;
    struct node{
        int next,to;
        ll v,w;
    }e[1000001];
    struct hh{
        int fa,edge;
    }pre[100001];
    int n,m,s,t,a[100001];
    int p,kp,kt,mp,mt;
    int head[100001],cnt=1;
    int inq[100001];
    ll d[100001],mi[100001];
    
    void add(int x,int y,int v,int w){
        e[++cnt].to=head[x];
        e[cnt].next=y;
        e[cnt].w=w;
        e[cnt].v=v;
        head[x]=cnt;
    }
    
    bool spfa(){
        memset(pre,0,sizeof(pre));
        for(int i=1;i<=n*2+3;i++) d[i]=INF;
        for(int i=1;i<=n*2+3;i++) mi[i]=INF;
        memset(inq,0,sizeof(inq));
        queue <int> que;
        que.push(s);
        d[s]=0;
        while(!que.empty()){
            int x=que.front();
            inq[x]=0;
            que.pop();
            for(int i=head[x];i;i=e[i].to){
                int k=e[i].next;
                if(d[k]>d[x]+e[i].w&&e[i].v){
                    d[k]=d[x]+e[i].w;
                    pre[k].fa=x;
                    pre[k].edge=i;
                    mi[k]=min(mi[x],e[i].v);
                    if(!inq[k]) que.push(k);
                    inq[k]=1;
                }
            }
        }
        return d[t]!=INF;
    }
    
    void EK(){
        ll cost=0,ret;   
        while(spfa()){
            ret=mi[t];
            
            for(int i=t;i!=s;i=pre[i].fa){
                e[pre[i].edge].v-=ret;
                e[pre[i].edge^1].v+=ret;
            }    
            cost+=ret*d[t];
        }
        printf("%lld
    ",cost);
        return ;
    }
    
    int main(){
        n=read();
        s=n*2+1;t=n*2+2;
        for(int i=1;i<=n;i++){
            a[i]=read();
        }
        p=read();kt=read();kp=read();mt=read();mp=read();
        for(int i=1;i<=n;i++){
            add(s,i,INF,p);
            add(i,s,0,-p);
            add(s,i+n,a[i],0);
            add(i+n,s,0,0);
            if(i+kt<=n){
                add(i+n,i+kt,INF,kp);
                add(i+kt,i+n,0,-kp);
            }
            if(i+mt<=n){
                add(i+n,i+mt,INF,mp);
                add(i+mt,i+n,0,-mp);
            }
            add(i,t,a[i],0);
            add(t,i,0,0);
            if(i<n){
                add(i+n,i+1+n,INF,0);
                add(i+1+n,i+n,0,0);
            }
        }
        EK();
        return 0;
    }
  • 相关阅读:
    文件权限---I
    python查看变量在内存中的地址
    Python3 基本数据类型
    print语法
    任务管理器启动项显示“没有可显示的启动项”如何解决?
    nginx 虚拟主机配置
    nginx 高级应用
    nginx 日志文件详解
    nginx 编译安装与配置使用
    python获取header脚本
  • 原文地址:https://www.cnblogs.com/zsq259/p/10516368.html
Copyright © 2020-2023  润新知