二分图匹配—匈牙利算法

1.概念

二分图:它的顶点只可以两个集合X,Y中的一个,所有的边关联在两个顶点中,恰好一个属于集合X,另一个属于集合Y。

匹配:图中的边必须一个端点在集合X中,一个端点在集合Y中,并且每个点只能使用一次。(也可能不存在边,这时匹配为0)


如果不是很理解,可以看看这个比较生动,形象

http://kukumayas.iteye.com/blog/1075610


2.匈牙利算法

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。它是一种用增广路径求二分图最大匹配的算法。


参考其中的匈牙利算法,较为详细

http://chhaj5236.blog.163.com/blog/static/1128810812009910102617216/



3.代码

n:集合X中元素个数
m:集合Y中元素个数
a[i][j]=1:i,j之间存在一条路
b[i]:标记点i是否已经使用
c[j]:也是一种标记,如c[j]=i,则i-j这条边就属于当前的匹配。
int n,m;
int **a;
int *b,*c;
int main()
{
   int i,j,ans=0;
   cin>>n>>m;
   a=new int*[n];
   for(i=0;i<n;i++)
   {
         a[i]=new int[m];
    }
    b=new int[m];
    c=new int[m];
    for(i=0;i<m;i++)
    {
       
        c[i]=-1;
     }
    for(i=0;i<n;i++)
    {        
       for(i=0;i<m;i++)
      {
          b[i]=0;     
       }
       if(find(i))
       {
           ans++;
        }
     }
}
bool find(int i)
{
     int j;
     for(j=0;j<m;j++)
     {
          if(a[i][j]==1&&b[j]==0)
          {
                b[j]=1;
                if(c[j]==-1||find(c[j]))//开始初始化c数组为-1。(对应下面的例子理解这一行,c[j]!=-1表示j点当前匹配中的某条边的端点,则计算find(c[j]))
                {                       //看与j相连的边的另一端点i是否也是其他边的端点!(有点绕,好好理解),如果也是其他边的端点,则交错路存在,否则没有
                       c[j]=i;
                        return true;
                 }
            }
     }
}

 

(图片转载于别的网站,忘了是什么网站)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值