hdu1083 Courses

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 ;
}

 

 


 

你可能感兴趣的:(HDU)