题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1083
分析:从第一个学生开始,先假定他任某一门课的课代表,然后再看第二个学生有没有选的,如果第二个学生他所学的课都有人预定了,那再看预定这些课的那些学生,如果他们之间有人还可以选其他的课,则让那个人选其他的,让第二个人预定那个人以前定的那门课,以些类推,最后看每门课是否都有人选.这就就答案了.
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
struct node{
int k;
int x[305];
}f[105];
int dis[305];///dis[i]=k表示任第i门课代表的是第k个学生
bool vis[305];
int n,p;
bool DFS(int k){
for(int i=0;i<f[k].k;++i){
if(vis[f[k].x[i]])continue;
vis[f[k].x[i]]=true;
///如果第f[k].x[i]门课没有任何人预定,或都是以前预定的那个人还可以先择其他课
if(!dis[f[k].x[i]]||DFS(dis[f[k].x[i]])){
dis[f[k].x[i]]=k; return true;
}
}
return false;
}
int main() {
int T; cin>>T;
while(T--) {
cin>>p>>n;
bool ok=true;
for(int i=1; i<=p; ++i) {
cin>>f[i].k;
for(int j=0;j<f[i].k;++j)
cin>>f[i].x[j];
}
memset(dis,0,sizeof(dis));///初始化,所有的课都没有课代表
for(int i=1;i<=p&&ok;++i){
memset(vis,0,sizeof(vis));///初始化,所有课都没有"预定"课代表
ok=DFS(i);
}
if(ok)puts("YES");
else puts("NO");
}
return 0;
}