题目链接:http://poj.org/problem?id=1274
思路:easy~~~
多汇点,多源点的最大流。 分别设一个源点汇点,即可。
将奶牛和stall编号编一起,奶牛和每个喜欢的stall的容量是1,源点和每个奶牛的容量是1,每个stall和汇点的容量是1,求最大流即可。
#include <iostream>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define maxn 500
#define inf 0x3f3f3f3f
int n,m;
int a[maxn];
int p[maxn];
int cap[maxn][maxn];
int flow[maxn][maxn];
queue<int> Q;
int main()
{
int dis,sumc,cnt;
while(~scanf("%d %d",&n,&m)){
memset(cap,0,sizeof(cap));
memset(flow,0,sizeof(flow));
for(int i = 1;i <= n;i ++){
scanf("%d",&cnt);
for(int j = 0;j < cnt;j ++){
scanf("%d",&dis);
cap[i][dis+n] = 1;
}
}
int s = 0, t = n + m + 1;
for(int i = 1; i <= n ;i ++){
cap[s][i] = 1;
}
for(int i = (n+1);i <= (n+m);i ++){
cap[i][t] = 1;
}
int f = 0;
for(;;){
memset(a,0,sizeof(a));
a[s]=inf;
Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int v=1;v<=t;v++){
if(!a[v] && cap[u][v]>flow[u][v]){
a[v] = min(a[u],cap[u][v] - flow[u][v]);
Q.push(v); p[v]=u;
}
}
}
if(a[t]==0) break;
for(int u=t;u!=s;u=p[u]){
flow[p[u]][u] += a[t];
flow[u][p[u]] -= a[t];
}
f += a[t];
}
printf("%d\n",f);
}
return 0;
}