poj 1469 COURSES (二分图模板应用 【*模板】 )
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 18454 | Accepted: 7275 |
Description
- 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
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
Sample Input
2
3 3
3 1 2 3
2 1 2
1 1
3 3
2 1 3
2 1 3
1 1
Sample Output
YES
NO
Source
题目解读:p门课,n个学生. 接下来p行,每行代表第i门课每行先输入这门课的学生数,然后在一次输入这些学生的编号。通过匈牙利算法问:能不能保证每门课至少都有一个学生. 算法要点:最大匹配数>=课程数p ?
匈牙利算法 代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm> using namespace std; vector<int>g[310];
int link[310], vis[310];
int p, n; bool match(int x)
{
for(int i=0; i<g[x].size(); i++ )
{
if(!vis[g[x][i]] )
{
vis[g[x][i]] = true;
if(link[g[x][i]]==-1 || match(link[g[x][i]]) )
{
link[g[x][i]] = x;
return true;
}
}
}
return false;
} int hungary()
{
int tot=0;
memset(link, 255, sizeof(link));
for(int i=1; i<=n; i++)
{
memset(vis, 0, sizeof(vis));
if(match(i) )
{
tot++;
}
}
return tot;
}
int main()
{
int t;
int i, j, k; scanf("%d", &t);
while(t--)
{
scanf("%d %d", &p, &n);
int dd, u;
for(i=1; i<=n; i++)
g[i].clear();
for(i=1; i<=p; i++)
{
scanf("%d", &dd);
while(dd--)
{
scanf("%d", &u);
g[u].push_back(i);
}
}
int ans = hungary();
if(ans >= p)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
Hopcroft-Karp 算法:
Hopcroft-Karp算法相比普通的匈牙利算法更快,所以当两边集合的点比较多时,为了快速完成匹配可以考虑这个算法,即使是有模板,但代码比较长且比较繁琐,容易写错。
敲的时候要特别注意!
H-K算法代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <algorithm> using namespace std;
int p, n;
vector<int>g[310];
int n1, n2;
int mx[310], my[310];
queue<int>que; int dx[310], dy[310];
bool vis[310]; bool find(int u)
{
for(int i=0; i<g[u].size(); i++)
{
if(!vis[g[u][i]] && dy[g[u][i]] == dx[u]+1 )
{
vis[g[u][i]] = true;
if(!my[g[u][i]] || find(my[g[u][i]]) )
{
mx[u] = g[u][i];
my[g[u][i]] = u;
return true;
}
}
}
return false;
} int matching()
{
memset(mx, 0, sizeof(mx));
memset(my, 0, sizeof(my));
int ans=0; while(true)
{
bool flag=false;
while(!que.empty())
que.pop();
memset(dx, 0, sizeof(dx));
memset(dy, 0, sizeof(dy));
for(int i=1; i<=n1; i++)
if(!mx[i] )
que.push(i);
while(!que.empty() )
{
int u=que.front();
que.pop();
for(int i=0; i<g[u].size(); i++ )
{
if(!dy[g[u][i]] )
{
dy[g[u][i]] = dx[u]+1;
if(my[g[u][i]])
{
dx[my[g[u][i]]] = dy[g[u][i]] + 1;
que.push(my[g[u][i]] );
}
else
flag=true;
}
}
}
if(!flag) break;
memset(vis, false, sizeof(vis));
for(int i=1; i<=n1; i++)
{
if(!mx[i] && find(i) )
ans++;
}
}
return ans;
} int main()
{
int t;
scanf("%d", &t);
int dd, u;
while(t--)
{
scanf("%d %d", &p, &n);
for(int i=1; i<=n; i++)
g[i].clear();
for(int i=1; i<=p; i++)
{
scanf("%d", &dd);
while(dd--)
{
scanf("%d", &u);
g[u].push_back(i);
}
}
n1=n; n2=p;
int ans = matching();
if(ans >= p )
printf("YES\n");
else
printf("NO\n"); }
return 0;
}
poj 1469 COURSES (二分图模板应用 【*模板】 )的更多相关文章
- POJ 1469 COURSES 二分图最大匹配 二分图
http://poj.org/problem?id=1469 这道题我绝壁写过但是以前没有mark过二分图最大匹配的代码mark一下. 匈牙利 O(mn) #include<cstdio> ...
- POJ 1274 The Perfect Stall || POJ 1469 COURSES(zoj 1140)二分图匹配
两题二分图匹配的题: 1.一个农民有n头牛和m个畜栏,对于每个畜栏,每头牛有不同喜好,有的想去,有的不想,对于给定的喜好表,你需要求出最大可以满足多少头牛的需求. 2.给你学生数和课程数,以及学生上的 ...
- poj 1469 COURSES(匈牙利算法模板)
http://poj.org/problem?id=1469 COURSES Time Limit: 1000MS Memory Limit: 10000K Total Submissions: ...
- Poj(1469),二分图最大匹配
题目链接:http://poj.org/problem?id=1469 COURSES Time Limit: 1000MS Memory Limit: 10000K Total Submissi ...
- POJ 1469 COURSES
COURSES Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 20478 Accepted: 8056 Descript ...
- poj 1469 COURSES 题解
COURSES Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21515 Accepted: 8455 Descript ...
- poj 1469 COURSES 解题报告
题目链接:http://poj.org/problem?id=1469 题目意思:有 N 个人,P个课程,每一个课程有一些学生参加(0个.1个或多个参加).问 能否使得 P 个课程 恰好与 P 个学生 ...
- poj——1469 COURSES
COURSES Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 24192 Accepted: 9426 Descript ...
- POJ 1469 COURSES(二部图匹配)
COURSES Time Limit: 1000MS Memory ...
随机推荐
- 【重点突破】——SVG技术动态随机绘制圆形
一.引言 在学习Canvas绘图技术时,做的是随机验证码的例子,在学习SVG绘图技术时,同样也有一个随机绘制的例子——动态随机绘制圆形.这个练习,即综合了多种SVG技术的知识点,又很具有艺术感,随机生 ...
- DevExpress控件之TreeList
基于v18.1 使用AppendNode方法手动赋值时,首先要添加treeListColumn 默认样式 修改后的样式 1 ...
- Java数据结构-线性表之静态链表
静态链表的定义: 节点由一个一维数组和一个指针域组成,数组用来存放数据元素,而指针域里面的指针(又称游标)用来指向下一个节点的数组下标. 这种链表称之为静态链表. 链表中的数组第一个和最后一个位置须要 ...
- 入门--JTBC系统学习(1)
下载代码 JTBC有还例如以下几类 JDK(1.6)+JSP(2.0)+MYSQL/SQLITE ASP.NET(2.0)+ACCESS/SQL SERVER PHP+MYSQL ASP(3.0)+A ...
- android开发笔记之fastboot的使用
fastboot命令大全 在终端中.我们输入: fastboot 对于这些命令.我不解释,慢慢使用.慢慢的就会明确是怎么回事了. android分区 分区 作用 splash1 开机画面.使用Nand ...
- 迁移,移动.vagrant.d目录
默认在 C:\Users\***\.vagrant.d 然后下面有boxes目录 想迁移到其它目录 setx VAGRANT_HOME "/d/.vagrant.d/" setx ...
- mapreduce代码实现入门
mapreduce代码主要包括三个类,map类.reduce类以及测试类! 以wordcount为例, map类为: static class WordMapper extends Mapper< ...
- Android-自定义广播不能用的可能的原因(sendbroadcast 不起效果)
参考博客:https://blog.csdn.net/chuyouyinghe/article/details/79424373 照着书上的源码将程序原封不动敲了一遍,但发现这特么怎么也收不到发出的广 ...
- python 基础 8.3 match方法和search方法
一,正则对象的split 方法 split(string[,maxsplit]) 按照能够匹配的字串讲string 分割后返回列表.maxsplit 用于指定最大分割次数,不指定将全部分割.来查找符合 ...
- protect,internal的区别
protected: 爷爷有一张银行卡,爸爸可以用,儿子也可以用,隔壁老王不可以用(因为老王跟爷爷没有继承关系) internal: 王总有一张银行卡,秘书可以用,经理可以用,王总儿子不可以用(因为银 ...