POJ 1719 Shooting Contest

/* 给定一个 r*c 的格子矩阵,有C发子弹,每列格子有2个白色的方块,在1,2,3,...c 列上开枪打白色的格子,打到一个,那么这个白色方块所在的行就算打到了,求怎样打,才能把所有的行全部打到,如果全部打到而且有多余的列,那么这列随便打一个方块就可以了,按列的1,2,3,4......C的顺序,输出要打的行号。很明显的一个二分匹配,普通的二分匹配算法就行了。*/

 

#include  < iostream >
#include 
< cstdio >
#include 
< algorithm >
#include 
< memory.h >
using   namespace  std;

#define  INF 0x7ffffff
#define  MAXN 4000
#define  MAXE 20000

struct  Edge{
    
int  u,v;
    
int  next;
}edge[MAXE];
int  net[MAXN],visit[MAXN],pre[MAXN];
int  nv,ne,index,r,c;
void  add_edge( const   int &  u,  const   int &  v)
{
    edge[index].next 
=  net[u];
    net[u] 
=  index;
    edge[index].v 
=  v;
    edge[index].u 
=  u;
    
++ index;
}
int  dfs( const   int &  u)
{
    
int  i,v;
    
for (i  =  net[u]; i  !=   - 1 ; i  =  edge[i].next)
    {
        v 
=  edge[i].v;
        
if ( ! visit[v])
        {
            visit[v] 
=   1 ;
            
if ( - 1   ==  pre[v]  ||  dfs(pre[v]))
            {
                pre[v] 
=  u;
                
return   1 ;
            }
        }
    }
    
return   0 ;
}
int  main()
{
    
int  i,j,k,h,tmp,sum,time,tmp1,tmp2,ans;
    scanf(
" %d " , & time);
    
while (time -- )
    {
        scanf(
" %d%d " , & r, & c);
        index 
=  ans  =   0 ;
        memset(net,
- 1 , sizeof (net));
        memset(pre,
- 1 , sizeof (pre));
        
for (i  =   1 ;i  <=  c;  ++ i)
        {
            scanf(
" %d%d " , & tmp1, & tmp2);
            add_edge(tmp1,i);
            add_edge(tmp2,i);
            add_edge(i
+ r,tmp1);
        }
        
if (c < r)
            ans 
=   - 1 ;
        
else
            
for (i  =   1 ;i  <=  r;  ++ i)
            {
                memset(visit,
0 , sizeof (visit));
                
if (dfs(i))
                    
++ ans;
            }
        
if (ans  <  r)
            printf(
" NO\n " );
        
else
        {
            
for (i  =   1 ;i  <=  c;  ++ i)
            {
                
if (i  !=   1 ) printf( "   " );
                
if (pre[i]  !=   - 1 )
                    printf(
" %d " ,pre[i]);
                
else
                    printf(
" %d " ,edge[net[i + r]].v);
            }
            printf(
" \n " );
        }
    }
    
return   0 ;
}

 

 

你可能感兴趣的:(test)