poj1469——COURSES

题目大意:给出N个学生登记对P种课程感兴趣的情况,一个学生可以选0、1...多门课,问能不能按规定形成一个有P个人的委员会,规定如下:委员会里的每个学生都代表一个不同的课程;每个课程都有一个课代表

输入:case个数

           第i个case的课程数P  学生数N

           第j个课程的学生个数Countj  学生号码...(学生号码一共Countj个,中间空格隔开)

输出:YES/NO

分析:二分图的最大匹配。最大匹配数=课程数 即可。这样就保证了一个课程匹配一个学生,而且不重复。

代码:转载自http://blog.csdn.net/u013899738/article/details/47275293

  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stack>  
  4. #include <queue>  
  5. #include <set>  
  6. #include <map>  
  7.   
  8. #define N 1000  
  9. using namespace std;  
  10.   
  11. int n,p,lin[N],cnt;//lin[i]:第个course相连的student  
  12. bool mp[N][N],used[N];  
  13.   
  14. bool searc(int a){//判断是否能构成新的增广序列的函数  
  15.     for(int j=1;j<=n;j++)  
  16.         if(mp[a][j]&&!used[j]){//连通且没用过  
  17.             used[j]=1;  
  18.             if(lin[j]==-1 || searc(lin[j])){//无配对或构成增广序列  
  19.                 lin[j]=a;  
  20.                 return true;  
  21.             }  
  22.     }//if  
  23.     return false;  
  24. }  
  25. int main(){  
  26.     int T,num,temp;  
  27.     scanf("%d",&T);  
  28.     while(T--){  
  29.         scanf("%d%d",&p,&n);  
  30.         cnt=0;  
  31.         memset(mp,0,sizeof(mp));  
  32.         memset(lin,-1,sizeof(lin));  
  33.         for(int i=1;i<=p;i++){  
  34.             scanf("%d",&num);  
  35.             for(int j=1;j<=num;j++){  
  36.                 scanf("%d",&temp);  
  37.                 mp[i][temp]=true;  
  38.             }//for_j  
  39.         }//for_i  
  40.         //匈牙利算法  
  41.         for(int i=1;i<=p;i++){  
  42.             memset(used,0,sizeof(used));  
  43.             if(searc(i)) cnt++;  
  44.         }  
  45.         if(p==cnt) printf("YES\n");  
  46.         else printf("NO\n");  
  47.     }//while  
  48.     return 0;  
  49. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值