题意:有P门课程和N个学生,每门课程有0-N个学生参加,问可不可以选出每门课的课代表,要求一个学生只能当一个课程的课代表。
思路:裸的二分匹配,匈牙利算法。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
int P, N;
bool path[120][320];
bool used[320];
int match[320];
bool Dfs(int x)
{
for (int i = 1; i <= N; i++)
{
if (!used[i] && path[x][i])
{
used[i] = true;
if (match[i]==-1 || Dfs(match[i]))
{
match[i] = x;
return true;
}
}
}
return false;
}
bool Matching()
{
int ans = 0;
memset(match,-1,sizeof(match));
for (int i = 1; i <= P; i++)
{
memset(used, false, sizeof(used));
if (Dfs(i))
ans++;
}
return ans==P;
}
int main(void)
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
scanf("%d", &T);
while (T--)
{
memset(path, false, sizeof(path));
scanf("%d %d", &P, &N);
for (int i = 1; i <= P; i++)
{
int num, x;
scanf("%d", &num);
while (num--)
{
scanf("%d", &x);
path[i][x] = true;
}
}
printf("%s\n", Matching()?"YES":"NO");
}
return 0;
}