匈牙利算法。
在于不停的找增广路。
#include<iostream>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int Maxn=555;
vector<int >g[Maxn];
int from[Maxn],use[Maxn];
int match(int x)
{
for(int i=0;i<g[x].size();i++){
if(!use[g[x][i]]){
use[g[x][i]]=1; //未被匹配
if(from[g[x][i]]==-1||match(from[g[x][i]])){ //这个学生未被匹配或者匹配这个学生的课还有其他匹配
from[g[x][i]]=x;
return 1;
}
}
}
return 0;
}
int hungry(int n)
{
int tot=0;
memset(from,255,sizeof(from)); //清空为-1
for(int i=1;i<=n;i++){
memset(use,0,sizeof(use));
if(match(i)) tot++;
}
return tot;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int p,n,i,j;
scanf("%d%d",&p,&n);
for(i=1;i<=p;i++){
g[i].clear();
int temp;
scanf("%d",&temp);
for(j=0;j<temp;j++){
int now;
scanf("%d",&now);
g[i].push_back(now);
}
}
if(p==hungry(p)) printf("YES\n");
else printf("NO\n");
}
return 0;
}