http://acm.hdu.edu.cn/showproblem.php?pid=1083

题目大意:有P个课程和N个学生,现题目要求两点:

1. every student in the committee represents a different course (a student can represent a course if he/she visits that course)
2. each course has a representative in the committee

现想组建一个委员会,委员会中的每个学生都要代表不同的课程,且每个课程都有它的代表。

算法分析:这正符合二分图最大匹配的条件。把课程作为二分图中X节点集合,得到最大匹配,如果匹配数等于课程数,则匹配与Y集合的交集,就可看成是这样一个委员会,则输出YES,否则,输出NO。

 

代码
#include<stdio.h>
#include
<string.h>
int P, N;
int cnt[102]; //cnt[i] 记录的是学过课程i的学生个数
int list[102][302]; //list[i][j]表示学过课程i的第j个学生的编号
int visy[302]; //用来记录二分图中Y集合中的点时候被访问过
int link[302]; //link[i] 表示当前学生编号为i的匹配课程
int can(int t)
{
int i, k;
for (i = 1; i <= cnt[t]; i++){
k
= list[t][i];
if (!visy[k]){
visy[k]
= 1;
if (link[k] == -1 || can(link[k])){
link[k]
= t;
return 1;
}
}
}

return 0;
}
int MaxMatch()
{
int i;
memset(link,
-1, sizeof(link));
for (i = 1; i <= P; i++){
memset(visy,
0, sizeof(visy));
if (!can(i))
return 0;
}
return 1;
}

int main()
{
int T, i, j, flag;
scanf(
"%d", &T);
while (T--){
scanf(
"%d%d", &P, &N);
for (i = 1; i <= P; i++){
scanf(
"%d", &cnt[i]);
for (j = 1; j <= cnt[i]; j++){
scanf(
"%d", &list[i][j]);
}
}
flag
= MaxMatch();
if (flag) puts("YES");
else puts("NO");
}
return 0;
}

 

 


 

posted on 2010-06-23 21:00  ylfdrib  阅读(407)  评论(0编辑  收藏  举报