二分匹配的问题,使用的是匈牙利算法,地址:http://acm.pku.edu.cn/JudgeOnline/problem?id=1469
#include "stdio.h"
#include
<string.h>
const int M = 505;
bool canmatch[M][M];
int ser(int leftnum,int rightnum,int cur,int* link,bool *used)
{
    
int i;
    
for(i=1;i<=rightnum;i++)
    
{
        
if( canmatch[cur][i]==1 && !used[i] )
        
{
            used[i]
=true;
            
if(link[i]==0||ser(leftnum,rightnum,link[i],link,used))
            
{
                link[i]
=cur;
                
return true;
            }

        }

    }

    
return false;
}


int Match( int leftnum ,int rightnum )
{
    
int ans=0 , i;
    bool 
*used = new bool[(rightnum+1)] ;
    
int *link = new int [(rightnum+1)] ;
    memset(link,
0,sizeof(int)*(rightnum+1));
    
for(i=1;i<=leftnum;i++)
    
{
        memset(used,
0,sizeof(bool)*(rightnum+1));
        
if(ser(leftnum,rightnum,i,link,used))
            ans
++;
    }

    
return ans;
}


void initm ( int n )
{

    
for ( int i=0; i<=n; i++ )
    
{
        
for ( int j=0; j<=n; j++ )
        
{
            canmatch[i][j] 
= false;
        }

    }

}


int main ()
{

    
int t;
    
int p, n;
    
int i, j;

    scanf ( 
"%d"&t );
    
while ( t -- )
    
{
        scanf ( 
"%d%d"&p, &n );

        
int count;
        initm ( p
<? n:p );
        
for ( i=1; i<=p; i++ )
        
{
            scanf ( 
"%d"&count );
            
int in;
            
for ( j=0; j<count; j++ )
            
{
                scanf ( 
"%d"&in );
                canmatch[ i ][ in ] 
= true;
            }

        }


        
if ( Match ( p, n ) == p )
        
{
            printf ( 
"YES\n" );
        }

        
else
        
{
            printf ( 
"NO\n" );
        }

    }

    
return 0;
}