• BZOJ 1221: [HNOI2001] 软件开发【最小费用最大流】


    Description

    某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供一块消毒毛巾,这种消毒毛巾使用一天后必须再做消毒处理后才能使用。消毒方式有两种,A种方式的消毒需要a天时间,B种方式的消毒需要b天(b>a),A种消毒方式的费用为每块毛巾fA, B种消毒方式的费用为每块毛巾fB,而买一块新毛巾的费用为f(新毛巾是已消毒的,当天可以使用);而且f>fA>fB。公司经理正在规划在这n天中,每天买多少块新毛巾、每天送多少块毛巾进行A种消毒和每天送多少块毛巾进行B种消毒。当然,公司经理希望费用最低。你的任务就是:为该软件公司计划每天买多少块毛巾、每天多少块毛巾进行A种消毒和多少毛巾进行B种消毒,使公司在这项n天的软件开发中,提供毛巾服务的总费用最低。

    Input

    第1行为n,a,b,f,fA,fB. 第2行为n1,n2,……,nn. (注:1≤f,fA,fB≤60,1≤n≤1000)

    Output

    最少费用

    Sample Input

    4  1  2  3  2  1                      
    8  2  1  6  

    Sample Output

    38 

    HINT

    Source

    最小费用最大流

    思路:建图对了很快就AC了,而网络流的建图越来越觉得和思考DP方程差不多了,DP方程首先要想的(也是难点)便是设计状态,而网络流建图首先要想的便是网络中边和点的含义,能否很好的把所有状态包含在构造出的图中是重点

    每天的毛巾显然有两种,一种是可以用的毛巾,一种是用过的毛巾,想了很久每一天代表一个点,但始终想不出有什么办法,于是把每天的每种毛巾看成一个点,就发现可行了,然后在设计出点的基础上,题目给出的各种限制,就是对应图上各种连边

    首先每天都可以有新毛巾,那就从源点到每天的新毛巾连一条边,容量为该天所需毛巾数,费用为f

    其次每天用过的毛巾都会产生旧毛巾,但是直接从新毛巾的点连过去会影响流到T的流量,因此直接从源点向旧毛巾连容量为毛巾数的边就好了 

    旧毛巾可以积累到下一天,于是每个旧毛巾的点顺次给下一个旧毛巾点连边

    然后就是A方式和B方式,A方式是将第i天的旧毛巾变成第i+a+1天的新毛巾

    B方式同理

    连好边后直接跑就行了 

    越来越感觉网络流=DP了  TUT

    #include<cstdio>

    #include<string.h>

    #include<math.h>

    #include<algorithm>

    #include<iostream>

    #include<queue>

    #define maxn 90000

    #define inf 0x3f3f3f3f

    using namespace std;

    int head[maxn],next[maxn],point[maxn],flow[maxn];

    int value[maxn],now=1,dist[maxn],pre[maxn];

    int x[maxn],n;

    void add(int x,int y,int f,int v)

    {

        next[++now]=head[x];

        head[x]=now;

        point[now]=y;

        flow[now]=f;

        value[now]=v;

        next[++now]=head[y];

        head[y]=now;

        point[now]=x;

        flow[now]=0;

        value[now]=-v;

    }

    int read()

    {

    int x=0,f=1;char ch=getchar();

    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}

    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

    return x*f;

    }

    int spfa(int s,int t)

    {

        for(int i=1;i<=2*n+10;i++)dist[i]=inf;

        dist[s]=0;dist[t]=inf;

        bool visit[maxn]={0};

        visit[s]=1;

        queue<int>q;

        q.push(s);

        while(!q.empty())

        {

            int u=q.front();

            q.pop();

            visit[u]=0;

            for(int i=head[u];i;i=next[i])

            {

                int k=point[i];

                if(dist[u]+value[i]<dist[k] &&flow[i])

                {

                    dist[k]=dist[u]+value[i];

                    pre[k]=i;

                    if(!visit[k])

                    {

                        visit[k]=1;

                        q.push(k);

                    }

                }

            }

        }

        if(dist[t]==inf)return 0;else return 1;

    }

    int main()

    {

        int a,b,f,fa,fb,ans=0;

        n=read();a=read();

        b=read();f=read();

        fa=read();fb=read();

        int s=maxn-10,t=maxn-12;

        for(int i=1;i<=n;i++)x[i]=read();

        for(int i=1;i<=n;i++)add(s,i*2+1,x[i],f);

        for(int i=1;i<=n;i++)add(s,i*2,x[i],0);

        for(int i=1;i<n;i++)add(i*2,(i+1)*2,inf,0);

        for(int i=1;i<=n-a;i++)add(i*2,(i+a+1)*2+1,inf,fa);

        for(int i=1;i<=n-b;i++)add(i*2,(i+b+1)*2+1,inf,fb);

        for(int i=1;i<=n;i++)add(i*2+1,t,x[i],0);

        while(spfa(s,t))

        {

            int u=pre[t],minx=flow[u];

            while(u)

            {

                minx=min(minx,flow[u]);

                u=pre[point[u^1]];

            }

            u=pre[t];

            while(u)

            {

                flow[u]-=minx;

                flow[u^1]+=minx;

                u=pre[point[u^1]];

            }

            ans+=dist[t]*minx;

        }

        printf("%d ",ans);

        return 0;

    }

  • 相关阅读:
    div+css之清除浮动
    ASP.NET repeater添加序号列的方法
    html中给图片添加热点
    jquery中read与js中onload区别
    从.net转型,聊聊最近一些面试,薪资和想法
    (9)分布式下的爬虫Scrapy应该如何做-关于ajax抓取的处理(一)
    数学之美--关于图论引申出来的爬虫构想
    (8)分布式下的爬虫Scrapy应该如何做-图片下载(源码放送)
    【转】Bloom Filter布隆过滤器的概念和原理
    【转】Python中的GIL、多进程和多线程
  • 原文地址:https://www.cnblogs.com/philippica/p/4137678.html
Copyright © 2020-2023  润新知