pku 1274 The Perfect Stall

pku 1274 The Perfect Stall
http://acm.pku.edu.cn/JudgeOnline/problem?id=1274
二分最大匹配
最大流用  匈牙利 或者最大流(建图 源点s连上所有的牛,所有的棚连上汇点t)
#include < iostream >
using     namespace   std;
 
#define   MAXN   201 
 
int   uN, vN;    //  u,v数目  
  bool   g[MAXN][MAXN];  //  g[i][j] 表示 xi与yj相连  
  int   xM[MAXN], yM[MAXN];   //   输出量  
  bool   chk[MAXN];   //  辅助量 检查某轮 y[v]是否被check  
bool   SearchPath(  int   u)
{
     
int   v;
     
for   (v  =   0  ; v  <  vN; v  ++  ){
         
if   (g[u][v]   &&     !  chk[v]){
            chk[v]  
=     true  ;
             
if   (yM[v]   ==     -   1     ||   SearchPath(yM[v])){
                yM[v]  
=   u;
                xM[u]  
=   v;
                 
return     true  ;
            } 
        } 
    } 
     
return     false  ;

 
 
int   MaxMatch()
{
     
int   u;
     
int   ret   =     0  ;
    memset(xM,  
-   1  ,   sizeof  (xM));
    memset(yM,  
-   1  ,   sizeof  (yM));
     
for   (u  =   0  ; u  <  uN; u  ++  ){
         
if   (xM[u]   ==     -   1  ){
            memset(chk,  
false  ,   sizeof  (chk));
             
if   (SearchPath(u)) ret  ++  ;
        } 
    } 
     
return   ret;

 
int  main()
{
    
    
while (scanf( " %d%d " , & uN, & vN) != EOF) {
        
int  i,j;
        memset(g,
0 , sizeof (g));
        
for (i = 0 ;i < uN;i ++ ) {
            
int  a,b;
            scanf(
" %d " , & a);
            
for (j = 0 ;j < a;j ++ ){
                scanf(
" %d " , & b);
                g[i][b
- 1 ] = 1 ;
            }
        }
        printf(
" %d\n " ,MaxMatch());
    }
    
return   0 ;
}
 
#include < iostream >
using   namespace  std;
 
#define  MAXN 410
#define  inf 2100000000
// 传入网络节点数n,容量mat,源点source,汇点sink
int  max_flow( int  n, int  mat[][MAXN], int  source, int  sink, int  flow[][MAXN]){
    
int  pre[MAXN],que[MAXN],d[MAXN],p,q,t,i,j;
    
if  (source == sink)  return  inf;
    
for  (i = 0 ;i < n;i ++ )
        
for  (j = 0 ;j < n;flow[i][j ++ ] = 0 );
    
for  (;;){
        
for  (i = 0 ;i < n;pre[i ++ ] = 0 );
        pre[t
= source] = source + 1 ,d[t] = inf;
        
for  (p = q = 0 ;p <= q &&! pre[sink];t = que[p ++ ])
            
for  (i = 0 ;i < n;i ++ )
                
if  ( ! pre[i] && (j = mat[t][i] - flow[t][i]))
                    pre[que[q
++ ] = i] = t + 1 ,d[i] = d[t] < j ? d[t]:j;
                
else   if  ( ! pre[i] && (j = flow[i][t]))
                    pre[que[q
++ ] = i] =- t - 1 ,d[i] = d[t] < j ? d[t]:j;
        
if  ( ! pre[sink])  break ;
        
for  (i = sink;i != source;)
            
if  (pre[i] > 0 )
                flow[pre[i]
- 1 ][i] += d[sink],i = pre[i] - 1 ;
            
else
                flow[i][
- pre[i] - 1 ] -= d[sink],i =- pre[i] - 1 ;
    }
    
for  (j = i = 0 ;i < n;j += flow[source][i ++ ]);
    
return  j;
}
int  mat[MAXN][MAXN],flow[MAXN][MAXN];
 
 
int  main()
 {
     
int  n,m;
     
int  s,t;
     
int  k,a,b;
     
while (scanf( " %d%d " , & n, & m) != EOF){
        memset(mat,
0 , sizeof (mat));
        memset(flow,
0 , sizeof (flow));
        
for ( int  i = 1 ;i <= n;i ++ ){
          mat[
0 ][i] = 1 ;
        }
//  s->1--n 
         for ( int  i  =  n + 1 ;i  <=  n + m;i ++ ){
           mat[i][n
+ m + 1 ] = 1 ;
        }
// (n+1)--(n+m)->t 
         for ( int  i = 1 ;i <= n;i ++ ){
           scanf(
" %d " , & k);
           
for ( int  j = 0 ;j < k;j ++ ){
             scanf(
" %d " , & a);
             mat[i][n
+ a] = 1 ;
           }
        }
        printf(
" %d\n " ,max_flow(n + m + 2 ,mat, 0 ,n + m + 1 ,flow));
     }
     
return   0 ;
 }


你可能感兴趣的:(pku 1274 The Perfect Stall)