[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); }