题解:
原点->食物建一个1
食物->牛见一个1
牛->牛'见一个1
牛'->饮料1
饮料->汇点1
代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=405; int q[N*N],n,m,sum,dis[N],k,d,x,y,ans,f[N],z,a[N][N]; int bfs() { memset(dis,0xff,sizeof dis); dis[1]=0; int l=0,r=1; q[1]=1; while (l<r) { int j=q[++l]; for (int i=1;i<=n;i++) if (dis[i]<0&&a[j][i]>0) { dis[i]=dis[j]+1; q[++r]=i; } } if (dis[n]>0)return 1; return 0; } int find(int x,int low) { int b=0; if (x==n)return low; for (int i=1;i<=n;i++) if (a[x][i]>0&&dis[i]==dis[x]+1&&(b=find(i,min(low,a[x][i])))) { a[x][i]-=b; a[i][x]+=b; return b; } return 0; } int main() { scanf("%d%d%d",&n,&m,&k); memset(a,0,sizeof a); for (int i=1;i<=n;i++)a[i+m+1][i+m+n+1]=1; for (int i=1;i<=n;i++) { scanf("%d%d",&x,&y); while (x--) { scanf("%d",&d); a[1][d+1]=a[d+1][i+m+1]=1; } while (y--) { scanf("%d",&d); a[d+2*n+m+1][2*n+m+k+2]=a[i+m+n+1][d+2*n+m+1]=1; } } n=n*2+m+k+2; ans=0;int t; while (bfs()) while (t=find(1,0x7fffffff))ans+=t; printf("%d\n",ans); }