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 ...
随机推荐
- 关于 Android 平台开发相关的有哪些推荐书籍?
转自:http://www.zhihu.com/question/19579609 作者:Shan Huang 链接:http://www.zhihu.com/question/19579609/an ...
- void f(int(&p)[3]){} 和void f(int(*p)[3]){}的差别
#include<iostream> using namespace std; void f(int(&p)[3]){ cout<<p[0]<& ...
- 日历插件js,jquery
常用的日历插件 DatePicker My97DatePicker 文章来源:刘俊涛的博客 地址:http://www.cnblogs.com/lovebing 欢迎关注,有问题一起学习欢迎留言. ...
- 4种使用webpack提升vue应用的方式
本文参考自:https://mp.weixin.qq.com/s?src=11×tamp=1526886111&ver=889&signature=u9SixhvlJ ...
- Cocos2d-x中Vector<T>容器以及实例介绍
Vector<T> 是Cocos2d-x 3.x推出的列表容器,因此它所能容纳的是Ref及子类所创建的对象指针,其中的T是模板,表示能够放入到容器中的类型,在Cocos2d-x 3.x中T ...
- 新安装的金蝶K3软件,初始化后,在基础资料中对于币别,科目,部门,客户等资料均无法新增,无法引出,等操作,K3CASysSet.dll
新装K3,新建的帐套.导入科目点菜单或新增button均无反应,币别.客户等辅助核算项目也新增也无法保存. 在电脑上新安装的金蝶K3软件.初始化后.在基础资料中对于币别,科目,部门,客户等资料均无法新 ...
- (五)解决jQuery和其它库的冲突
在jQuery库中,几乎所有的插件都被限制在它的命名空间里.全局的对象都很好地存储在jQuery命名空间里,因此当把jQuery和其它javascript类库一起使用时,不会引起冲突.(注意:默认情况 ...
- BCG菜单button的简单使用
一,新建一个BCGprojectCBCGPMenuButton,基于对话框. 二.添加一个button,并关联一个CButton类型的变量m_btn1.然后手动将类型改CBCGPMenuButton成 ...
- ALLEGRO修改位号回注ORCAD原理图
资料:ALLEGRO修改位号回注ORCAD原理图 https://wenku.baidu.com/view/54e221e114791711cd7917e2.html?re=view
- VMware Workstation 永久许可证密钥
VMware是功能最强大的虚拟机软件,用户可在虚拟机同时运行各种操作系统,进行开发.测试.演示和部署软件,虚拟机中复制服务器.台式机和平板环境,每个虚拟机可分配多个处理器核心.主内存和显存. VMwa ...