http://poj.org/problem?id=1469
类似网络流的思想,
该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int N=300+7;
const int M=100+7;
int mp[M][N],f[N];
bool used[N];
int n,m;
bool finds(int x)
{
for(int i=1;i<=n;i++)
if(!used[i]&&mp[x][i])
{
used[i]=1;
if(f[i]==-1||finds(f[i]))//让f[i] 换个课程(即增广) 因为used[i] 已经标记
{
f[i]=x;
return 1;
}
}
return 0;
}
int sum()
{
int res=0;
for(int i=1;i<=m;i++)
{
memset(used,0,sizeof used);
if(finds(i)) res++;//本题这 可以优化 如果有一个没有 找到 答案就是 NO
}
return res;
}
int main()
{
int t,tt=0,x,y,z;
scanf("%d",&t);
while(t--)
{
memset(mp,0,sizeof mp);
memset(f,-1,sizeof f);
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
{
scanf("%d",&x);
for(int j=0;j<x;j++)
{
scanf("%d",&y);
mp[i][y]=1;
}
}
printf("%s",sum()==m?"YES":"NO");
//for(int i=1;i<=p;i++) cout<<f[i]<<endl; 如果可以找到完全披风匹配f 就是ans
}
return 0;
}