http://acm.hdu.edu.cn/showproblem.php?pid=1083
分析:二分图匹配,一个学生代表一门课程(单向匹配[课程]->[学生])
#include<iostream>
#include<cstring>
#include<cstdio>
const int NM=305;
bool a[NM][NM],flag[NM];
int link[NM],n,m;
bool Find(int x)
{
int i;
for(i=1;i<=n;i++)
{
if(a[x][i]&&!flag[i]) //i学生选择了x课程&&i学生还没有担任课代表
{
flag[i]=1;
if(link[i]==-1||Find(link[i])) //i学生没有担任某门课课代表||该课程还可以找其他人代替课代表
{
link[i]=x;
return 1;
}
}
}
return 0;
}
int main()
{
int T,i,j,t,x,sum;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&m,&n);
memset(a,0,sizeof(a));
memset(link,-1,sizeof(link));
for(i=1;i<=m;i++)
{
scanf("%d",&t);
for(j=0;j<t;j++)
{
scanf("%d",&x);
a[i][x]=1;
}
}
sum=0;
for(i=1;i<=m;i++)
{
memset(flag,0,sizeof(flag));
if(Find(i)) //每次为一个课程选择课代表的时候,每个学生都要从头考虑,直到找到合适的课代表为止
sum++;
}
if(sum==m) printf("YES\n"); //m=>courses
else printf("NO\n");
}
return 0;
}