[wikioi2930]填报志愿(裸题)
2015-03-17 13:40
204 查看
填报志愿
题目描述 Description高考已经结束,而志愿填报正在进行中~
吴校长的学校里有n位同学,每位同学有ki个愿意去的大学。而在吴老师的省份中,有m所大学有招生名额。根据往年的经验,对于每所大学(编号为ci),学校中最多只会有一人考上。因此为了避免志愿冲突,每年吴校长都要安排老师对同学们的志愿进行调整。
今年吴校长找到了你来帮忙,请你编程计算,在不冲突的情况下,最多能有多少同学顺利填报志愿,填报志愿的方案又是怎样的。
输入描述 Input Description
第一行,一个数n。
接下来的n行,每行的第一个数为ki,接下来有ki个数,表示第i个同学愿意去的大学的编号。 下一行,一个数m。 下一行,m个数,为m个大学的编号。保证大学编号递增。
输出描述 Output Description
第一行,一个数,为在不冲突的情况下,最多能有多少同学顺利填报志愿。
接下来的若干行,输出填报志愿的方案。每行两个数,第一个数为学生编号,第二个数为大学编号,以空格隔开。若有多种可行方案,输出字典序最小的一种。
样例输入 Sample Input
3
2 1 2
3 2 4 5
2 2 3
5
1 3 4 5 6
样例输出 Sample Output
3
1 1
2 4
3 3
数据范围及提示 Data Size & Hint
0 < n<=1000, 0< ki<=20, 0 < m<=2000, 学生的编号为1~n, 大学的编号为1~5000。同学愿意去的大学不一定招生。
又是一道裸的二分图匹配,可以练练手。
#include <cstdio> #include <cstring> #define MAXN 1005 using namespace std; int g[MAXN * 5][MAXN * 5], b[MAXN * 5]; int link[MAXN * 5], num[MAXN * 5]; int n, m; int ans = 0; int find(int x) { for (int j = 1; j <= m; ++j) { int y = num[j]; if (b[y] == 0 && g[x][y] == 1) { b[y] = 1; if (link[y] == 0 || find(link[y]) == 1) { link[y] = x; return 1; } } } return 0; } int main() { int t; memset(g, 0, sizeof(g)); scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%d", &t); for (int j = 1; j <= t; ++j) { int y; scanf("%d", &y); g[i][y] = 1; } } scanf("%d", &m); for (int i = 1; i <= m; ++i) scanf("%d", &num[i]); for (int i = 1; i <= n; ++i) { memset(b, 0, sizeof(b)); ans = ans + find(i); } printf("%d\n", ans); return 0; }
谢谢大家
相关文章推荐
- 如何填报第一志愿
- 海南2008年本科提前批填报志愿资格分数线
- 最新河北省本科、专科、高职院校大学名单-填报志愿辅助资料
- 生活随笔:填报志愿
- 昨天填报了志愿
- 生活随笔:填报志愿
- 高考志愿填报 别迷信“大数据”
- 广东省填报专科院校志愿
- 2930 填报志愿
- 填报志愿慎重选择第一专业 别把保押在转专业上
- 80老翁谈人生(7):如何填报高考志愿表不上当?
- 高考志愿填报指南:未来十大热门专业预测
- 80老翁谈人生(8):考生志愿应该自己填报
- 1060: 填报志愿 [水题]
- 填报高考志愿的“三大纪律,八项注意”
- 关于志愿填报的相关问题及其回答
- codevs2930 填报志愿-还是二分图
- 高考志愿填报技巧
- 龙海高考志愿填报“达人”邓溪清出书授“秘笈”
- 80老翁谈人生(16):高考志愿如何填报?