匈牙利算法详解:
http://blog.csdn.net/dark_scope/article/details/8880547
二分图最大匹配裸题 http://poj.org/problem?id=1469
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define N 1000
using namespace std;
int n,p,lin[N],cnt;//lin[i]:第个course相连的student
bool mp[N][N],used[N];
bool searc(int a){//判断是否能构成新的增广序列的函数
for(int j=1;j<=n;j++)
if(mp[a][j]&&!used[j]){//连通且没用过
used[j]=1;
if(lin[j]==-1 || searc(lin[j])){//无配对或构成增广序列
lin[j]=a;
return true;
}
}//if
return false;
}
int main(){
int T,num,temp;
scanf("%d",&T);
while(T--){
scanf("%d%d",&p,&n);
cnt=0;
memset(mp,0,sizeof(mp));
memset(lin,-1,sizeof(lin));
for(int i=1;i<=p;i++){
scanf("%d",&num);
for(int j=1;j<=num;j++){
scanf("%d",&temp);
mp[i][temp]=true;
}//for_j
}//for_i
//匈牙利算法
for(int i=1;i<=p;i++){
memset(used,0,sizeof(used));
if(searc(i)) cnt++;
}
if(p==cnt) printf("YES\n");
else printf("NO\n");
}//while
return 0;
}