caioj 1123 上课(二分图匹配)
来源:互联网 发布:大乐网络代理什么游戏 编辑:程序博客网 时间:2024/06/04 19:36
题目描述
(看完题意,你将要假设什么是公牛,什么是母牛,~~~)
一个星期有7天,每天有12节课。
有n门课程,但是有些课程上课的时间是冲突的,
求最多能上多少门课程。
Input
第一行为整数 n (1 <= n <= 300), 表示课程的总数。下来n行表示n门课程的信息。每行第一个数为整数 t (1 <= t <= 7*12), 表示学生可以学习该门课程的时间段总数。下来t对整数,每对整数为 p (1 <= p <= 7) and q (1 <= q <= 12), 表示该门课程在每个星期的第p天的第q节课上课。
Output
输出一行,最多能上多少门课。
Sample Input
5
1 1 1
2 1 1 2 2
1 2 2
2 3 2 3 3
1 3 3
Sample Output
4
这是一道二分图匹配的题,但是要转化模型,思考一下就可以看出要匹配的应该是课程n与上课时间。然后就是一道模板题了。但是在写代码的时候就会发现一个问题就是课程n与上课的时间如何进行匹配储存。我这里是用一个二维的数组分别存课程与时间的。然后在dfs函数里面加个参数,1为课程,2为时间,在搜索时候比较容易转化。这是我的代码:
#include<cstdio>#include<vector>#include<cstring>#define maxn 307using namespace std;vector<int> lesson[maxn][3];int match[maxn][3];int n;bool check[maxn][3];int ans;bool dfs(int z,int y){ int c=lesson[z][y].size(); int p; if(y==1)p=2; if(y==2)p=1; for(int i=0;i<c;i++) { int v=lesson[z][y][i]; if(!check[v][y]) { if(match[v][y]==0||dfs(match[v])) { match[v][y]=z; match[z][y]=v; return true; } } } return false;}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { int h;scanf("%d",&h); for(int j=1;j<=h;j++) { int x,y; scanf("%d%d",&x,&y); lesson[i][1].push_back(x*12+y); lesson[x*12+y][2].push_back(n); } } for(int i=1;i<=n;i++) ( if(!match[n][1]) { memset(check,0,sizeof(check)); if(dfs(n,1))ans++; } ) printf("%d\n",ans); return 0;}
我用邻接表做比较麻烦,用链式前向星就比较简单了,别人的代码:
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; #define N 310 int soursenum; int map[N][90]; int match[N]; bool use[N]; bool find(int u) //查询匹配的课程 { for(int i = 1; i <= 84; ++i) { if(!use[i] && map[u][i]) { use[i] = true; if(match[i] == -1 || find(match[i])) { match[i] = u; return true; } } } return false; } int sum() { int sumall = 0; for(int i = 1; i <= soursenum; ++i) { memset(use, false, sizeof(use)); if(find(i)) sumall++; } return sumall; } int main() { int everynum; int day, time; while(scanf("%d", &soursenum) != EOF) { memset(map, 0, sizeof(map)); memset(match, -1, sizeof(match)); for(int k = 1; k <= soursenum; ++k) { scanf("%d", &everynum); for(int i = 1; i <= everynum; ++i) { scanf("%d%d", &day, &time); map[k][(day - 1) * 12 + time] = 1; //巧妙转换 } } printf("%d\n", sum()); } return 0; }
是时候学一下链式前向星了,哈哈哈。
阅读全文
0 0
- caioj 1123 上课(二分图匹配)
- HDU2063--过山车(二分匹配,二分图)
- poj2356(二分图匹配)
- 二分图(行列匹配)
- 二分图(最大匹配)
- hdoj2119_Matrix(二分图匹配)
- BZOJ1191(二分图匹配)
- bzoj1059(二分图匹配)
- hdu1083(二分图匹配)
- poj1486(二分图匹配)
- hdu1281(二分图匹配)
- poj1486 (二分图匹配)
- HDU1528(二分图匹配)
- POJ3041(二分图匹配)
- POJ3057(二分图匹配)
- [caioj]KMP总结(?)
- hdu2444(二分图判定+二分图匹配)
- hdu2444 二分图匹配(判断二分图)
- 【一句话解释一个技术点】初心
- c#和c++数据类型对应关系
- Android中取消EditText自动获得焦点
- 关于MyEclipse打war包的问题
- 博客新开通
- caioj 1123 上课(二分图匹配)
- JavaScript 30 Day -- 06 Array
- Android Architecture Components+MVP 实战
- IntelliJ Idea取消Could not autowire. No beans of 'xxxx' type found的错误提示
- poj1961——Period
- Robot Framework
- Python语言简介
- Java开发常用gitignore配置记录
- java Date常用转换