本题为基本的二分图最大匹配,使用匈牙利算法即可。
#include <iostream>
using namespace std;
const int MAXN = 305;
int map[MAXN][MAXN]; //课程和学生的匹配
int visit[MAXN]; //访问状态
int match[MAXN]; //学生代表的课程
int P, N; //课程数,学生数
int find(int x) //寻找增广路
{
for (int i = 1; i <= N; i++)
{
if (!visit[i] && map[x][i]) //当前学生未被访问,且与可以代表该课程
{
visit[i] = 1;
//当前学生没有代表课程,或者从其代表的课程能够找到增广路
if (match[i] == -1 || find(match[i]))
{
match[i] = x;
return 1;
}
}
}
return 0;
}
int main()
{
int T;
int num, stu; //代表每门课的学生人数,学生编号
cin >> T;
while (T--)
{
memset(map, 0, sizeof(map));
memset(match, -1, sizeof(match));
cin >> P >> N;
for (int i = 1; i <= P; i++)
{
cin >> num;
for (int j = 0; j < num; j++)
{
cin >> stu;
map[i][stu] = 1;
}
}
int total = 0; //二分图的最大匹配数
for (int i = 1; i <= P; i++) //计算二分图的最大匹配
{
memset(visit, 0, sizeof(visit));
if (find(i)) //如果有增广路,则最大匹配数加一
total++;
}
if (total == P)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
继续加油。