zoukankan      html  css  js  c++  java
  • POJ1149

    原题链接

    题意简述

    农场里有m(m103)个猪圈,接下来依次有n(n100)位顾客要来买猪。初始每个猪圈中都有不超过103只猪。
    i位顾客有ai把钥匙,分别为{k1,...,kai}。当第i位顾客到来时,Mirko可以打开对应的ai个猪圈,卖给他不大于bi只猪,然后将这ai个猪圈中剩余的猪任意分配,最后锁好这些猪圈并把钥匙还给顾客。
    求Mirko最多能卖出多少只猪。

    题解

    最大流。
    nm个点表示这n个人来的时候的m个猪圈,再建n个点表示n个顾客。首先,源点向时刻1的猪圈连一条容量等同于初始猪数的边;每个猪圈都对下一时刻的自己连+边;每个顾客都向汇点连一条容量为bi的边。然后对于顾客i来的时候被打开的ai个猪圈,每个都向顾客i和下一个时刻的这ai个猪圈连+边,表示这些猪圈之间可以随意调换。
    更好的建模方法见 [网络流建模汇总][Edelweiss] 第一题。

    代码

    //PIGS
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    inline char gc()
    {
        static char now[1<<16],*S,*T;
        if(S==T) {T=(S=now)+fread(now,1,1<<16,stdin); if(S==T) return EOF;}
        return *S++;
    }
    inline int read()
    {
        int x=0; char ch=gc();
        while(ch<'0'||'9'<ch) ch=gc();
        while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
        return x; 
    }
    int const NM=1e5+10;
    int const INF=0x7FFFFFFF;
    int n,m,s,t;
    int k[1001];
    int cnt,h[NM];
    struct edge{int v,c,nxt;} ed[NM<<1];
    void edAdd(int u,int v,int c)
    {
        cnt++; ed[cnt].v=v,ed[cnt].c=c,ed[cnt].nxt=h[u],h[u]=cnt;
        cnt++; ed[cnt].v=u,ed[cnt].c=0,ed[cnt].nxt=h[v],h[v]=cnt;
    }
    int dpt[NM]; int q[NM],op,cl;
    bool bfs()
    {
        op=cl=0; memset(dpt,0,sizeof dpt);
        dpt[q[++cl]=s]=1;
        while(op<cl)
        {
            int u=q[++op]; if(u==t) break;
            for(int i=h[u];i;i=ed[i].nxt)
            {
                int v=ed[i].v,c=ed[i].c;
                if(dpt[v]==0 && c) dpt[q[++cl]=v]=dpt[u]+1;
            }
        }
        if(dpt[t]==0) return false;
        else return true;
    }
    int fill(int u,int in)
    {
        if(u==t || in==0) return in;
        int out=0;
        for(int i=h[u];i;i=ed[i].nxt)
        {
            int v=ed[i].v,c=ed[i].c;
            if(dpt[v]!=dpt[u]+1 || !c) continue;
            int flow=fill(v,min(in-out,c));
            if(flow==0) dpt[v]=0;
            else out+=flow,ed[i].c-=flow,ed[i^1].c+=flow;
        }
        return out;
    }
    int main()
    {
        m=read(); n=read(); s=0; t=n*m+n+1;
        cnt=1;
        for(int i=1;i<=m;i++) edAdd(0,i,read());
        for(int p=1;p<=n-1;p++)
        {
            int a=read();
            for(int i=1;i<=m;i++) edAdd((p-1)*m+i,p*m+i,INF);
            for(int i=1;i<=a;i++) k[i]=(p-1)*m+read(),edAdd(k[i],n*m+p,INF);
            for(int i=1;i<=a;i++)
                for(int j=1;j<=a;j++) edAdd(k[i],k[j]+m,INF);
            edAdd(n*m+p,t,read());
        }
        int a=read();
        for(int i=1;i<=a;i++) k[i]=(n-1)*m+read(),edAdd(k[i],n*m+n,INF);
        edAdd(n*m+n,t,read());
        int ans=0;
        while(bfs()) ans+=fill(s,INF);
        printf("%d
    ",ans);
        return 0;
    }

    注意

    最后的m个猪圈就不要再向下一时刻建边了。

  • 相关阅读:
    VUE课程参考---2、VUE基本使用
    VUE课程---1、VUE课程介绍
    JS数组常用方法---3、pop方法使用及原理
    JavaScript中数组元素删除的七大方法汇总
    Stack的三种含义
    JS数组常用方法---6、reverse方法
    数据库水平切分的实现原理解析---分库,分表,主从,集群,负载均衡器
    服务框架HSF分析之一容器启动
    淘宝HSF服务的原理以及简单的实现
    DAS 原文出自【比特网】
  • 原文地址:https://www.cnblogs.com/VisJiao/p/8485763.html
Copyright © 2011-2022 走看看