HDU1281求二分图的关键匹配数

HDU1281求二分图的关键匹配数
http://acm.hdu.edu.cn/showproblem.php?pid=1281
比较猎人打鸟问题,可以将车看做是子弹,每个车都有x,y坐标,可将其看做边,行数和列数看成是两个集合的点,该题就变为求最多的匹配边。
关键匹配就是指在保证最大匹配的前提下,不能缺少的匹配。也就是说如果缺少这对匹配,那么所求的匹配数不是最大匹配。
#include  < iostream >

using   namespace  std;

const   int  M = 101 ;
bool  g[M][M];
bool  visit[M];
int   link[M];
int   x[M * M],y[M * M]; // 记录匹配边,用于计算关键匹配
int   m,n,k;

bool  find( int  i)
{
    
int  j;
    
for (j = 1 ;j <= m;j ++ )
    {
        
if (g[i][j]  &&   ! visit[j])
        {
            visit[j]
= true ;
            
if (link[j] == 0   ||  find(link[j]))
            {
                link[j]
= i;
                
return   true ;
            }
        }
    }
    
return   false ;
}

int  result()
{
    
int  i,res = 0 ;
    memset(link,
0 , sizeof (link)); // 注意link数组要在这里做初始化,因为link数组要用多次
     for (i = 1 ;i <= n;i ++ )
    {
        memset(visit,
0 , sizeof (visit));
        
if (find(i))
            res
++ ;
    }
    
return  res;
}

int  main()
{
    
int  t,l,c,count = 0 ;
    
while (cin >> n >> m >> k)
    {
        count
++ ;
        memset(g,
0 , sizeof (g));
        
for (t = 0 ;t < k;t ++ )
        {
            cin
>> x[t] >> y[t];
            g[x[t]][y[t]]
= true ;
        }
        l
= result();
        c
= 0 ;
        
for (t = 0 ;t < k;t ++ )        
        {
            g[x[t]][y[t]]
= false ; // 将(x[t],y[t])设为不连通,求最大匹配,如果变小,说明该边为关键匹配边
             if (result() < l)      
                c
++ ;
            g[x[t]][y[t]]
= true // 还原状态
        }
        printf(
" Board %d have %d important blanks for %d chessmen.\n " ,count,c,l);
    }
    
return   0 ;
}


你可能感兴趣的:(HDU1281求二分图的关键匹配数)