题意:有p门课,n个学生,给出每门课选了的学生,问能否选出恰好p个学生,使每个学生选不同课,每门课有不同的学生
思路:二分图匹配
代码如下:
(匈牙利算法)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define CLR(a,b) memset(a,b,sizeof(a));
using namespace std;
const int maxn=305;
vector<int> g[maxn];
int from[maxn];
bool use[maxn];
int tot;
int p,n;
bool match(int x)
{
for(int i=0;i<g[x].size();++i)
if(!use[g[x][i]])
{
use[g[x][i]]=true;
if(from[g[x][i]]==-1||match(from[g[x][i]]))
{
from[g[x][i]]=x;
return true;
}
}
return false;
}
int hungary()
{
tot=0;
CLR(from,-1);
for(int i=1;i<=n;++i)
{
CLR(use,0);
if(match(i))++tot;
}
return tot;
}
int main()
{
// freopen("data.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&p,&n);
for(int i=0;i<=n;++i)
{
g[i].clear();
}
for(int i=1;i<=p;++i)
{
int cnt;
scanf("%d",&cnt);
for(int j=0;j<cnt;++j)
{
int s;
scanf("%d",&s);
g[s].push_back(i);
}
}
int ans=hungary();
if(ans==p)
printf("YES\n");
else printf("NO\n");
}
return 0;
}