匈牙利算法

这个是学了好久的算法了。。终于腾出时间来写这篇博客了,希望借此加深一下这个算法的理解~

先来一个匈牙利算法的模板。

int M[MAX][MAX];int visit[MAX];
int un,vn,n,m;
int pre[MAX];

bool can(int u){
      int v,j;
      for(v=1;v<=vn;v++){
            if(0==visit[v]&&1==M[u][v]){
                  visit[v]=1;
                  if(-1==pre[v]||can(pre[v])){
                        pre[v]=u;
                        return 1;
                }                       
            }
      }
      return 0;
}

int Solve(){
      int i,sum=0;
      memset(pre,0xff,sizeof(pre));
      for(i=1;i<=un;i++){
            memset(visit,0,sizeof(visit));
            if(can(i))
                  sum++;
      }
      return sum;
}

二分图是这样一个图,它的顶点可以分类两个集合X和Y,所有的边关联在两个顶点中,恰好一个属于集合X,另一个属于集合Y。
最大匹配:图中包含边数最多的匹配称为图的最大匹配。匈牙利就是来解决二分图的最大匹配问题的。

匈牙利算法的基本模式就是:

初始时最大匹配为空
while 找得到增广路径
    do 把增广路径加入到最大匹配中去

下面给出一个伪代码:

bool 寻找从k出发的对应项出的可增广路
{
	while (从邻接表中列举k能关联到顶点j)
	{
		if (j不在增广路上)
		{
			把j加入增广路;
			if (j是未盖点 或者 从j的对应项出发有可增广路)
			{
				修改j的对应项为k;
				则从k的对应项出有可增广路,返回true;
			}
		}
	}
	则从k的对应项出没有可增广路,返回false;
}
 
void 匈牙利hungary()
{
	for i->1 to n
	{
		if (则从i的对应项出有可增广路)
			匹配数++;
	}
	输出 匹配数;
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值