建图:
构造一个源点和一个汇点
源点与牛相连,容量为1
牛与牛棚相连,容量为1
牛棚与汇点相连,容量为1
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stack>
#include<queue>
#include<math.h>
#include<cstdio>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = 500;
const int inf = 0x7fffff;
int dist[maxn];
int pre[maxn];
int minf[maxn];
int flow[maxn][maxn];
int c[maxn][maxn];
bool vis[maxn];
int maxflow(int s,int t)
{
int f,u;
queue<int> q;
mem(flow,0);
f=0;
while(1)
{
q.push(s);
mem(vis,0);
mem(minf,0);
vis[s]=1;
minf[s]=inf;
while(!q.empty())
{
u=q.front();
q.pop();
for(int i=0;i<=t;i++)
{
if(!vis[i] && c[u][i]-flow[u][i]>0)
{
vis[i]=1;
minf[i]=min(minf[u],c[u][i]-flow[u][i]);
q.push(i);
pre[i]=u;
}
}
}
f+=minf[t];
if(minf[t]==0) break;
for(int i=t;i!=s;i=pre[i])
{
flow[i][pre[i]] -= minf[t];
flow[pre[i]][i] += minf[t];
}
}
return f;
}
int main()
{
int n,m,a,p;
while(cin>>n>>p)
{
int s=0;
int t=n+p+1;
mem(c,0);
for(int i=1;i<=n;i++)
{
cin>>m;
c[s][i]=1;
for(int j=1;j<=m;j++)
{
cin>>a;
c[i][n+a-1]=1;
}
}
for(int i=1;i<=p;i++)
c[n+i-1][t]=1;
cout<<maxflow(s,t)<<endl;
}
return 0;
}