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个猪圈就不要再向下一时刻建边了。

  • 相关阅读:
    BZOJ2821 作诗(Poetize) 【分块】
    BZOJ2724 蒲公英 【分块】
    Codeforces 17E Palisection 【Manacher】
    BZOJ2565 最长双回文串 【Manacher】
    Codeforces 25E Test 【Hash】
    CODEVS3013 单词背诵 【Hash】【MAP】
    HDU2825 Wireless Password 【AC自动机】【状压DP】
    HDU2896 病毒侵袭 【AC自动机】
    HDU3065 病毒侵袭持续中【AC自动机】
    HDU2222 Keywords Search 【AC自动机】
  • 原文地址:https://www.cnblogs.com/VisJiao/p/8485763.html
Copyright © 2011-2022 走看看