暑假-二分图-C - Courses

来源:互联网 发布:学淘宝美工 编辑:程序博客网 时间:2024/05/18 21:39

题意:有p门课程,n个学生,然后又p行,每行都m个编号,代表课程i【i从课程1到课程p】

被学生j选中【学生j愿意当课程i的课代表】,问能否能没门课程都有一个课代表【每个人只能选

一门课程当课代表。

思路:二分图的最大匹配,匈牙利算法模板。

注意枚举的是课程,是课程选学生,并且判断是否满足所有课程都能选到学生。

而不是枚举学生选课程【刚开始就被这个坑了下】。

#include<iostream>#include<cstring>#include<vector>using namespace std;const int MAXP = 105;const int MAXN = 305;vector<int>map[MAXP];//map[i][j]为1表示学生j选择课程iint vis[MAXN];//学生i已经选过int link[MAXN];//学生i选择课程link[i]int p, n;void init()//初始化{memset(link, -1, sizeof(link));for (int i = 0; i < MAXP; i++){map[i].clear();}}bool find(int x){for (int i = 0; i < map[x].size(); i++)//枚举该课程的所有学生{int u = map[x][i];//u为学生编号if (!vis[u])//该学生没被选中{vis[u] = 1;//标记已选中if (link[u] == -1 || find(link[u])){//如果v没有匹配,或者v已经匹配了,但从cy[v]出发可以找到增广路link[u] = x;//把x匹配给学生ureturn true;}}}return false;}int main(){int t,m,s;cin >> t;while (t--){init();//初始化cin >> p >> n;for (int i = 0; i < p; i++)//课程i{cin >> m;//选择课程i的学生数目for (int j = 0; j < m; j++){cin >> s;//学生编号map[i].push_back(s);}}int ans = 0;for (int i = 0; i < p; i++)//注意枚举的是课程,不是学生!{memset(vis, 0, sizeof(vis));if (find(i))//如果所以课程能选到课代表{ans++;}}if (ans == p)//如果所以课程都能选到课代表{cout << "YES" << endl;}else{cout << "NO" << endl;}}return 0;}


0 0