题意:
有N个学生和P门课程,让你判断能否构成最大匹配。先输入一个T,表示有T组测试数据;在输入N和P,P表示有P门课程,N表示有N个学生。之后有P行,比如:
a a1 a2 a3 a4 a5---第一行。1与a1,a2,a3,a4,a5有匹配。
b b1 b2 b3-----第二行。2与b1,b2,b3有匹配。
如果匹配数等于学生数目则YES;否则为NO;
上交模板,因为用了bfs增广一系列路径,所以更快……
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define PI acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define sca(a) scanf("%d",&a)
#define sc(a,b) scanf("%d%d",&a,&b)
#define pri(a) printf("%d\n",a)
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define MM 50005
#define MN 500
#define INF 0x7fffffff
#define eps 1e-7
using namespace std;
typedef long long ll;
int nx,ny,vis[MM],mx[MM],my[MM],dx[MM],dy[MM];
vector<int>e[MM];
queue<int>q;
bool dfs(int u)
{
int i,l=e[u].size();
for(i=0;i<l;i++)
{
int v=e[u][i];
if(!vis[v]&&dy[v]==dx[u]+1)
{
vis[v]=1;
if(!my[v]||dfs(my[v]))
{
mx[u]=v;
my[v]=u;
return true;
}
}
}
return false;
}
int HK() //Hopcroft_Karp算法
{
mem(mx,0); mem(my,0);
int ans=0;
while(1)
{
int flag=0,i;
while(!q.empty()) q.pop();
mem(dx,0); mem(dy,0);
for(i=1;i<=nx;i++) if(!mx[i]) q.push(i);
while(!q.empty())
{
int u=q.front(),l=e[u].size(); q.pop();
for(i=0;i<l;i++)
{
int v=e[u][i];
if(!dy[v])
{
dy[v]=dx[u]+1;
if(my[v])
{
dx[my[v]]=dy[v]+1;
q.push(my[v]);
}
else flag=1;
}
}
}
if(!flag) break;
mem(vis,0);
for(i=1;i<=nx;i++)
if(!mx[i]&&dfs(i)) ans++;
}
return ans;
}
int main()
{
int t;
sca(t);
while(t--)
{
int u,v,i,a;
sc(nx,ny);
for(i=0;i<=nx;i++) e[i].clear();
for(u=1;u<=nx;u++)
{
sca(a);
for(i=0;i<a;i++)
sca(v),e[u].push_back(v);
}
puts(HK()==nx?"YES":"NO");
}
return 0;
}