COURSES
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 17777   Accepted: 7007

Description

Consider a group of N students and P courses. Each student visits zero, one or more than one courses. Your task is to determine whether it is possible to form a committee of exactly P students that satisfies simultaneously the conditions:

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

Input

Your program should read sets of data from the std input. The first line of the input contains the number of the data sets. Each data set is presented in the following format: 



P N 

Count1 Student1 1 Student1 2 ... Student1 Count1 

Count2 Student2 1 Student2 2 ... Student2 Count2 

... 

CountP StudentP 1 StudentP 2 ... StudentP CountP 



The first line in each data set contains two positive integers separated by one blank: P (1 <= P <= 100) - the number of courses and N (1 <= N <= 300) - the number of students. The next P lines describe in sequence of the courses �from course 1 to course P,
each line describing a course. The description of course i is a line that starts with an integer Count i (0 <= Count i <= N) representing the number of students visiting course i. Next, after a blank, you抣l find the Count i students, visiting the course, each
two consecutive separated by one blank. Students are numbered with the positive integers from 1 to N. 

There are no blank lines between consecutive sets of data. Input data are correct. 

Output

The result of the program is on the standard output. For each input data set the program prints on a single line "YES" if it is possible to form a committee and "NO" otherwise. There should not be any leading blanks at the start of the line.

Sample Input

  1. 2
  2. 3 3
  3. 3 1 2 3
  4. 2 1 2
  5. 1 1
  6. 3 3
  7. 2 1 3
  8. 2 1 3
  9. 1 1

Sample Output

  1. YES
  2. NO

Source

题意:有P门课,N个学生,每门课仅仅能相应一个人,可是单个人能够相应多门课。求最大匹配是否等于P。

题解:匈牙利也能够解,看到书上介绍了这个HK算法,时间复杂度要更低,于是尝试了下,可是...写起来真是太麻烦了。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <queue>
  4.  
  5. #define maxn 305
  6. #define maxp 105
  7. #define maxm maxn * maxp
  8. #define inf 0x3f3f3f3f
  9.  
  10. int head[maxp], id, p, n, dis;
  11. struct Node {
  12. int v, next;
  13. } E[maxm];
  14. int dx[maxp], dy[maxn], cx[maxp], cy[maxn];
  15. bool visy[maxn];
  16.  
  17. void AddEdge(int u, int v) {
  18. E[id].v = v;
  19. E[id].next = head[u];
  20. head[u] = id++;
  21. }
  22.  
  23. void GetMap() {
  24. int k, v, i; id = 0;
  25. scanf("%d%d", &p, &n);
  26. memset(head, -1, sizeof(int) * (p + 1));
  27. for(i = 1; i <= p; ++i) {
  28. scanf("%d", &k);
  29. while(k--) {
  30. scanf("%d", &v);
  31. AddEdge(i, v);
  32. }
  33. }
  34. }
  35.  
  36. bool searchPath() {
  37. std::queue<int> Q;
  38. int i, u, v; dis = inf;
  39. memset(dx, 0, sizeof(int) * (p + 1));
  40. memset(dy, 0, sizeof(int) * (n + 1));
  41. for(i = 1; i <= p; ++i) {
  42. if(!cx[i]) Q.push(i);
  43. }
  44. while(!Q.empty()) {
  45. u = Q.front(); Q.pop();
  46. if(dx[u] > dis) break;
  47. for(i = head[u]; i != -1; i = E[i].next) {
  48. if(!dy[v = E[i].v]) {
  49. dy[v] = dx[u] + 1;
  50. if(!cy[v]) dis = dy[v];
  51. else {
  52. dx[cy[v]] = dy[v] + 1;
  53. Q.push(cy[v]);
  54. }
  55. }
  56. }
  57. }
  58. return dis != inf;
  59. }
  60.  
  61. int findPath(int u) {
  62. int i, v;
  63. for(i = head[u]; i != -1; i = E[i].next) {
  64. if(!visy[v = E[i].v] && dx[u] + 1 == dy[v]) {
  65. visy[v] = 1;
  66. if(dy[v] == dis && cy[v]) continue;
  67. if(!cy[v] || findPath(cy[v])) {
  68. cy[v] = u; cx[u] = v;
  69. return 1;
  70. }
  71. }
  72. }
  73. return 0;
  74. }
  75.  
  76. int MaxMatch() {
  77. int ans = 0, i;
  78. memset(cx, 0, sizeof(int) * (p + 1));
  79. memset(cy, 0, sizeof(int) * (n + 1));
  80. while(searchPath()) {
  81. memset(visy, 0, sizeof(bool) * (n + 1));
  82. for(i = 1; i <= p; ++i)
  83. if(!cx[i]) ans += findPath(i);
  84. }
  85. return ans;
  86. }
  87.  
  88. void Solve() {
  89. printf(MaxMatch() == p ? "YES\n" : "NO\n");
  90. }
  91.  
  92. int main() {
  93. // freopen("stdin.txt", "r", stdin);
  94. int t;
  95. scanf("%d", &t);
  96. while(t--) {
  97. GetMap();
  98. Solve();
  99. }
  100. return 0;
  101. }

POJ1469 COURSES 【二分图最大匹配&#183;HK算法】的更多相关文章

  1. 二分图最大匹配:匈牙利算法的python实现

    二分图匹配是很常见的算法问题,一般用匈牙利算法解决二分图最大匹配问题,但是目前网上绝大多数都是C/C++实现版本,没有python版本,于是就用python实现了一下深度优先的匈牙利算法,本文使用的是 ...

  2. 51nod 2006 飞行员配对(二分图最大匹配) 裸匈牙利算法 求二分图最大匹配题

    题目: 题目已经说了是最大二分匹配题, 查了一下最大二分匹配题有两种解法, 匈牙利算法和网络流. 看了一下觉得匈牙利算法更好理解, 然后我照着小红书模板打了一遍就过了. 匈牙利算法:先试着把没用过的左 ...

  3. "《算法导论》之‘图’":不带权二分图最大匹配(匈牙利算法)

    博文“二分图的最大匹配.完美匹配和匈牙利算法”对二分图相关的几个概念讲的特别形象,特别容易理解.本文介绍部分主要摘自此博文. 还有其他可参考博文: 趣写算法系列之--匈牙利算法 用于二分图匹配的匈牙利 ...

  4. POJ 1469 COURSES 二分图最大匹配 二分图

    http://poj.org/problem?id=1469 这道题我绝壁写过但是以前没有mark过二分图最大匹配的代码mark一下. 匈牙利 O(mn) #include<cstdio> ...

  5. 二分图最大匹配(匈牙利算法)简介& Example hdu 1150 Machine Schedule

    二分图匹配(匈牙利算法) 1.一个二分图中的最大匹配数等于这个图中的最小点覆盖数 König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数.如果你还不知 ...

  6. 【模板】二分图最大匹配(匈牙利算法)/洛谷P3386

    题目链接 https://www.luogu.com.cn/problem/P3386 题目大意 给定一个二分图,其左部点的个数为 \(n\),右部点的个数为 \(m\),边数为 \(e\),求其最大 ...

  7. LightOJ 1356 Prime Independence 二分图最大独立集,HK算法

    这个题唯一需要说的就是普通的匈牙利算法是O(nm)的,过不了 然后HK算法可以O(n^0.5m),这个算法可以每次找很多同样长度的最短增广路 分析见:http://www.hardbird.net/l ...

  8. HDU-1083 Courses 二分图 最大匹配

    题目链接:https://cn.vjudge.net/problem/HDU-1083 题意 有一些学生,有一些课程 给出哪些学生可以学哪些课程,每个学生可以选多课,但只能做一个课程的代表 问所有课能 ...

  9. POJ1469 COURSES 二分图匹配 匈牙利算法

    原文链接http://www.cnblogs.com/zhouzhendong/p/8232649.html 题目传送门 - POJ1469 题意概括 在一个大矩阵中,有一些障碍点. 现在让你用1*2 ...

随机推荐

  1. c语言 c++ 实现查看本地ip,外网ip, 本地主机名,查看http网址对应的ip

    /******************************************************************************* 作者 :邓中强 Email :1246 ...

  2. PHP 下基于 php-amqp 扩展的 RabbitMQ 简单用例 (五) -- 自动 ACK、手动 ACK、NACK

    以 Direct 类型的 交换机和 Queue 的 get 方法为例. producer.php // 连接设置 $conConfig = [ 'host' => '127.0.0.1', 'p ...

  3. vim common usage

    vim normal模式下 1.c+i+分隔符,删除分隔符里面的内容(不删除分隔符,c+a+分隔符则包括分隔符一起删掉) 如将光标位于'%s : %d years old ' 中,此时按c+i+'   ...

  4. torch.nn.Embedding理解

    Pytorch官网的解释是:一个保存了固定字典和大小的简单查找表.这个模块常用来保存词嵌入和用下标检索它们.模块的输入是一个下标的列表,输出是对应的词嵌入. torch.nn.Embedding(nu ...

  5. 诊断:CLSRSC-400: A system reboot is required to continue installing.

    Linux7.5安装Grid Infrastructure 12.2.0.1时,在root.sh时会报错 2018/01/30 09:19:28 CLSRSC-330: Adding Clusterw ...

  6. GNU编译器学习 --> 如何链接外部库【Linking with external libraries】

    库也就是我们常说的library,一个库是若干个已经编译过的目标文件(.obj)的集合,它可以被链接到程序里.那么我们最常见的使用就是,我们在编程时会调用一些函数,这些函数别人已经写好了,它就放在库里 ...

  7. Centos6.5下 执行“ll”提示“-bash: ll: command not found”

    ll 是 ls -l的别名,之所所以 ll出现错误是因为没有定义别名. 如果要实现ll 命令,可以做如下操作: 编辑 ~./bashrc 添加 ls -l 的别名为 ll即可 [root@Centos ...

  8. PDO、PDOStatement、PDOException

    最近在学PDO  比较详细的资料 出处:http://blog.csdn.net/hsst027/article/details/23682003 PDO中包含三个预定义的类,它们分别是PDO.PDO ...

  9. python while、continue、break

    while循环实现用户登录 _user = "tom" _passwd = "abc123" counter = 0 while counter < 3: ...

  10. 第二十三节:scrapy爬虫识别验证码(二)图片验证码识别

    图片验证码基本上是有数字和字母或者数字或者字母组成的字符串,然后通过一些干扰线的绘制而形成图片验证码. 例如:知网的注册就有图片验证码 首先我们需要获取验证码图片,通过开发者工具我们可以得到验证码ur ...