zoukankan      html  css  js  c++  java
  • 网络流与线性规划24题 之 餐巾计划问题

    算法实现题8-10 餐巾计划问题(习题8-21)
    «问题描述:
    一个餐厅在相继的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
    中。
    输入文件示例 输出文件示例

    input.txt

    3 10 2 3 3 2

    5
    6

    7

    output.txt

    145

    【建模方法】
    经典构图题。将每一天拆成两个点i, i’,加如下6条边:
    (s, i, ri, p)——在第i天可以买至多ri个餐巾,每块p分;
    (i, t, ri, 0)——第i天要用ri块餐巾;
    (s, i’, ri, 0)——第i天用剩的ri块旧餐巾;
    (i’, i+m, ∞, f)——第i天的旧餐巾送到快洗部,每块f分;
    (i’, i+n, ∞, s)——第i天的旧餐巾送到慢洗部,每块s分;
    (i’, i’+1, ∞, 0)——第i天的旧餐巾可以留到第i+1天再处理;
    求一次最小费用流即为结果。(引自《网络流建模汇总》by Edelweiss)

    code如下:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define INF 0x3f3f3f3f
    using namespace std;
    int N,p,m,f,n,s,S,T,ecnt,ans,first[2100],nxt[1000100];
    struct Edge{int u,v,cap,cost;}e[1000100];
    bool vis[2100];
    int d[2100],q[2100];
    void Link(int a,int b,int w,int c)
    {
        e[++ecnt].u=a,e[ecnt].v=b,e[ecnt].cap=w,e[ecnt].cost=c;
        nxt[ecnt]=first[a],first[a]=ecnt;
        e[++ecnt].u=b,e[ecnt].v=a,e[ecnt].cap=0,e[ecnt].cost=-c;
        nxt[ecnt]=first[b],first[b]=ecnt;
    }
    bool spfa()
    {
        memset(vis,false,sizeof(vis));
        for(int i=S;i<=T;i++)d[i]=INF;//search for mininum;
        int head=0,tail=1;
        q[0]=T,vis[T]=true,d[T]=0;
        while(head^tail){
            int now=q[head++];
            if(head==2000)head=0;
            for(int i=first[now];i;i=nxt[i])
                if(d[e[i].v]>d[now]-e[i].cost&&e[i^1].cap){
                    d[e[i].v]=d[now]+e[i^1].cost;
                    if(!vis[e[i].v]){
                        vis[e[i].v]=true;
                        q[tail++]=e[i].v;
                        if(tail==2000)tail=0;
                    }
                }
            vis[now]=false;
        }
        return d[S]^INF;
    }
    int dfs(int x,int f)
    {
        vis[x]=true;
        if(!(x^T))return f;
        int used=0,w;
        for(int i=first[x];i;i=nxt[i])
            if(!vis[e[i].v]&&e[i].cap&&d[x]-e[i].cost==d[e[i].v]){
                w=f-used;
                w=dfs(e[i].v,min(e[i].cap,w));
                e[i].cap-=w;e[i^1].cap+=w;
                ans+=w*e[i].cost;
                used+=w;
                if(used==f)return f;
            }
        return used;
    }
    void zkw()
    {
        while(spfa()){
            vis[T]=true;
            while(vis[T]){
                memset(vis,false,sizeof(vis));
                dfs(S,INF);
            }
        }
    }
    int main()
    {
        scanf("%d%d%d%d%d%d",&N,&p,&m,&f,&n,&s);
        S=0,T=N*2+1,ecnt=1;
        for(int i=1;i<=N;i++){
            int x;
            scanf("%d",&x);
            Link(S,i,x,0);
            Link(S,i+N,INF,p);
            Link(i+N,T,x,0);
            if(i+1<=N)Link(i,i+1,INF,0);
            if(i+m<=N)Link(i,i+N+m,INF,f);
            if(i+n<=N)Link(i,i+N+n,INF,s);
        }
        zkw();
        printf("%d
    ",ans);
        return 0;
    }
    



  • 相关阅读:
    iOS crash 追终 ,iOS 如何定位crash 位置
    ios 性能优化策略
    如何提升代码编译的速度 iOS
    关于iOS的runtime
    iOS __block 与 __weak
    spring-boot-framework 如何自动将对象返回成json格式
    spring-boot 热部署 intellij IDE(开发过程)
    MAVEN中的插件放在哪个dependcies里面
    css3 RGBA
    css3 loading 效果3
  • 原文地址:https://www.cnblogs.com/keshuqi/p/5957756.html
Copyright © 2011-2022 走看看