[USACO07OPEN]吃饭Dining

https://www.luogu.org/problemnew/show/2891

#include<cstdio>
#include<algorithm>
#include<queue>
#define N 501
#define M N*N
using namespace std;
int src,decc,ans;
int from[N],to[M],nxt[M],tot=1;
int cap[M];
int cur[N],lev[N];
queue<int>q;
void add(int u,int v,int f)
{
    to[++tot]=v;
    nxt[tot]=from[u];
    from[u]=tot;
    cap[tot]=f;
    to[++tot]=u;
    nxt[tot]=from[v];
    from[v]=tot;
    cap[tot]=0;
}
bool bfs()
{
    while(!q.empty()) q.pop();
    for(int i=src; i<=decc; i++) cur[i]=from[i],lev[i]=-1;
    q.push(src);
    lev[src]=0;
    int now;
    while(!q.empty()) {
        now=q.front();
        q.pop();
        for(int i=from[now]; i; i=nxt[i]) {
            if(lev[to[i]]==-1&&cap[i]>0) {
                lev[to[i]]=lev[now]+1;
                if(to[i]==decc) return true;
                q.push(to[i]);
            }
        }
    }
    return false;
}
int dinic(int now,int flow)
{
    if(now==decc) return flow;
    int rest=0,delta;
    for(int &i=cur[now]; i; i=nxt[i]) {
        if(lev[to[i]]>lev[now]&&cap[i]>0) {
            delta=dinic(to[i],min(cap[i],flow-rest));
            if(delta) {
                cap[i]-=delta;
                cap[i^1]+=delta;
                rest+=delta;
                if(rest==flow) break;
            }
        }
    }
    if(rest!=flow) lev[now]=-1;
    return rest;
}
int main()
{
    int n,f,d,fi,di,x;
    scanf("%d%d%d",&n,&f,&d);
    decc=(n<<1|1)+f+d+1;
    for(int i=1; i<=f; i++) add(src,(n<<1|1)+i,1);
    for(int i=1; i<=d; i++) add((n<<1|1)+f+i,decc,1);
    for(int i=1; i<=n; i++) add(i<<1,i<<1|1,1);
    for(int i=1; i<=n; i++) {
        scanf("%d%d",&fi,&di);
        for(int j=1; j<=fi; j++) {
            scanf("%d",&x);
            add((n<<1|1)+x,i<<1,1);
        }
        for(int j=1; j<=di; j++) {
            scanf("%d",&x);
            add(i<<1|1,(n<<1|1)+f+x,1);
        }
    }
    while(bfs()) ans+=dinic(src,N);
    printf("%d",ans);
}
原文地址:https://www.cnblogs.com/shandongs1/p/8093787.html