This question is mainly on page 235 of the white book (challenge programming competition, 2nd Edition). The process of map building is very ingenious. Breaking a cow into two points, adding a super source point and a super sink point, becomes a very obvious maximum flow.. In addition, the varieties on pages 213-215 of the white book are summarized very well and comprehensively. In the future, we should learn and use them flexibly
The SAP adjacency table template I used for the maximum flow has not been initialized.. Be sure to pay attention next time..
Attach AC Code:
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; const int MAX=1010; int n; struct Edge { int to, next, cap, flow; }edge[MAX*MAX]; int tot,head[MAX]; int gap[MAX],dep[MAX],pre[MAX],cur[MAX]; void add(int u,int v,int w) { edge[tot].to=v;edge[tot].cap=w;edge[tot].flow=0; edge[tot].next=head[u]; head[u]=tot++; edge[tot].to=u;edge[tot].cap=0;edge[tot].flow=0; edge[tot].next=head[v];head[v]=tot++; } int sap(int st,int en,int n) { memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int i,u=st; pre[u]=-1; gap[0]=n; int maxflow=0; while(dep[st]<n) { if(u==en) { int mindis=INF; for(i=pre[u];i!=-1;i=pre[edge[i^1].to]) if(mindis>edge[i].cap-edge[i].flow) mindis = edge[i].cap-edge[i].flow; for(i=pre[u];i!=-1;i=pre[edge[i^1].to]) { edge[i].flow+=mindis; edge[i^1].flow-=mindis; } u=st; maxflow+=mindis; continue; } bool flag=false; int v; for(i=cur[u];i!=-1;i=edge[i].next) { v=edge[i].to; if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u]) { flag=true; cur[u]=pre[v]=i; u=v; break; } } if(flag) { u=v; continue; } else { int mindis=n; for(i=head[u];i!=-1;i=edge[i].next) if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<mindis) { mindis=dep[edge[i].to]; cur[u]=i; } gap[dep[u]]--; if(gap[dep[u]]==0) break; dep[u]=mindis+1; gap[dep[u]]++; if(u!=st) u=edge[pre[u]^1].to; } } return maxflow; } int main() { int f,d; while(scanf("%d%d%d",&n,&f,&d)==3) { //Pay attention to initialization!!! tot=0; memset(head,-1,sizeof(head)); int k=f+d; int i,fi,di,x; for(i=1;i<=2*n;i+=2) { scanf("%d%d",&fi,&di); while(fi--) { scanf("%d",&x); add(x,k+i,1); } add(k+i,k+i+1,1); while(di--) { scanf("%d",&x); add(k+i+1,f+x,1); } } k+=2*n; int s=k+1,t=k+2; for(i=1;i<=f;i++) add(s,i,1); for(i=1;i<=d;i++) add(f+i,t,1); k+=2; printf("%d\n",sap(s,t,k)); } return 0; }