zoukankan      html  css  js  c++  java
  • BZOJ_3280_小R的烦恼_最小费用最大流

    BZOJ_3280_小R的烦恼_最小费用最大流

    Description

    小R最近遇上了大麻烦,他的程序设计挂科了。于是他只好找程设老师求情。善良的程设老师答应不挂他,但是要
    求小R帮助他一起解决一个难题。问题是这样的,程设老师最近要进行一项邪恶的实验来证明P=NP,这个实验一共
    持续n天,第i天需要a[i]个研究生来给他搬砖。研究生毕竟也是人,所以雇佣研究生是需要钱的,机智的程设老师
    已经联系好了m所大学,第j所大学共有l[j]个研究生,同时雇佣这所大学的一个研究生需要p[j]元钱。本来程设老
    师满心欢喜的以为,这样捡最便宜的max{a[i]}个研究生雇来,就可以完成实验;结果没想到,由于他要求硕士生
    们每天工作25个小时不许吃饭睡觉上厕所喝水说话咳嗽打喷嚏呼吸空气,因此一天下来给他搬砖的所有研究生都会
    进入濒死状态。濒死状态的研究生,毫无疑问,就不能再进行工作了。但是机智的老师早早联系好了k家医院,第i
    家医院医治一个濒死的研究生需要d[i]天,并且需要q[i]元钱。现在,程设老师想要知道,最少花多少钱,能够在
    这n天中满足每天的需要呢?若无法满足,则请输出”impossible”。注意,由于程设老师良心大大的坏,所以他
    是可以不把濒死的研究生送去医院的!。

    Input

    本题包含多组数据;第一行是一个数T(T<=11),表示数据组数,以下T组数据。
    对于每一组数据,第一行三个数,n,m,k;
    以下一行n个数,表示a[1]…a[n]
    接着一行2m个数,表示l[1],p[1]…l[n],p[n]
    接着一行2k个数,表示d[1],q[1]…d[n],q[n]
    n,m,k<=50,其余数均小于等于100.

    Output

    对于每组数据以样例的格式输出一行,两个数分别表示第几组数据和最少钱数。

    Sample Input

    2
    3 2 1
    10 20 30
    40 90 15 100
    1 5
    3 2 1
    10 20 30
    40 90 15 100
    2 5

    Sample Output

    Case 1: 4650
    Case 2: impossible
    样例解释:
    买下90块钱的那40个研究生,另外再买10个100块钱的。这样,第一天用完的10个人全部送到医院,那么他们在第
    三天可以继续使用;同时,第二天和第三天都用新的研究生来弥补,这样一共需要花费40*90 + 10*100 + 5*10 =
    4650元。

    类似餐巾计划问题,将人拆成两个点(i,i')分别表示活的和死的。
    对学校有S->1(l[j],p[j])。对于第i天剩下的:S->i'(a[i],0)。
    i->i+1(inf,0) i'-i'+1(inf,0)  医院:i'->i+d[i](inf,q[i]) 流出去:i->T(a[i],0)。
     
    代码:
    #include <cstdio>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 1050
    #define M 1000050
    #define S (n+n+1)
    #define T (n+n+2)
    #define inf 1<<30
    int head[N],to[M],nxt[M],val[M],flow[M],cnt,n,m,K,a_[N],l_[N],p_[N],d_[N],q_[N];
    int Q[N],l,r,dis[N],inq[N],path[N],sum,TTT;
    inline void add(int u,int v,int f,int c) {
        to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f; val[cnt]=c;
        to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0; val[cnt]=-c;
    }
    bool spfa() {
        memset(dis,0x3f,sizeof(dis));
        memset(path,0,sizeof(path));
        l=r=0; Q[r++]=S; dis[S]=0; inq[S]=1;
        while(l!=r) {
            int x=Q[l++],i;inq[x]=0; if(l==T) l=0;
            for(i=head[x];i;i=nxt[i]) {
                if(dis[to[i]]>dis[x]+val[i]&&flow[i]) {
                    dis[to[i]]=dis[x]+val[i];
                    path[to[i]]=i^1;
                    if(!inq[to[i]]) {
                        inq[to[i]]=1; Q[r++]=to[i];
                        if(r==T) r=0;
                    }
                }
            }
        }
        return path[T];
    }
    void mcmf() {
        TTT++;
        int maxf=0,minc=0;
        while(spfa()) {
            int i,nf=1<<30;
            for(i=T;i!=S;i=to[path[i]]) {
                nf=min(nf,flow[path[i]^1]);
            }
            maxf+=nf;
            for(i=T;i!=S;i=to[path[i]]) {
                minc+=nf*val[path[i]^1];
                flow[path[i]]+=nf;
                flow[path[i]^1]-=nf;
            }
        }
        // printf("%d %d %d
    ",maxf,minc,sum);
        if(maxf<sum) {
            printf("Case %d: impossible
    ",TTT);
        }else {
            printf("Case %d: %d
    ",TTT,minc);
        }
    }
    void solve() {
        memset(head,0,sizeof(head)); cnt=1; sum=0;
        int i,j;
        scanf("%d%d%d",&n,&m,&K);
        for(i=1;i<=n;i++) scanf("%d",&a_[i]),add(i,T,a_[i],0),sum+=a_[i],add(S,i+n,a_[i],0);
        for(i=1;i<=m;i++) scanf("%d%d",&l_[i],&p_[i]),add(S,1,l_[i],p_[i]);
        for(i=1;i<=K;i++) scanf("%d%d",&d_[i],&q_[i]);
        for(i=1;i<=n;i++) {
            if(i!=n) add(i,i+1,inf,0),add(i+n,i+n+1,inf,0);
            for(j=1;j<=K;j++) {
                if(i+d_[j]+1<=n) add(i+n,i+d_[j]+1,inf,q_[j]);
            }
        }
        mcmf();
    }
    int main() {
        int cs;
        scanf("%d",&cs);
        while(cs--) {
            solve();
        }
    }
    
  • 相关阅读:
    BZOJ 3295 【CQOI2011】 动态逆序对
    POJ 3714 Raid
    树状数组区间修改加区间查询
    codevs 2606 约数和问题
    UOJ #150 【NOIP2015】 运输计划
    分享知识-快乐自己:IDEA 导入(web)项目并部署到 Tomcat
    分享知识-快乐自己:配置(各种)环境变量
    分享知识-快乐自己:什么是MVC
    分享知识-快乐自己:SpringBoot 使用注解API的方式定义启动端口号
    分享知识-快乐自己:Oracle中定义及使用同义词
  • 原文地址:https://www.cnblogs.com/suika/p/9127980.html
Copyright © 2011-2022 走看看