匈牙利算法

 匈牙利算法是用来求二分图的最大匹配的,它的核心问题就是找增广路径。匈牙利算法的时间复杂度为O(VE), 
 其中V为二分图左边的顶点数,E为二分图中边的数目。

 增广路的特性:
 (1)有奇数条边。
 (2)起点在二分图的左半边,终点在右半边。
 (3)路径上的点一定是一个在左半边,一个在右半边,交替出现。
 (4)整条路径上没有重复的点。
 (5)起点和终点都是目前还没有配对的点,而其它所有点都是已经配好对的。
 (6)路径上的所有第奇数条边都不在原匹配中,所有第偶数条边都出现在原匹配中。
 (7)最后,也是最重要的一条,把增广路径上的所有第奇数条边加入到原匹配中去,并把增广路径中的所有第偶
   数条边从原
   匹配中删除(这个操作称为增广路径的取反),则新的匹配数就比原匹配数增加了1个。

 很多问题都可以转化为二分图匹配模型。二分图有如下几种常见变形:

 (1)二分图的最小顶点覆盖 
 最小顶点覆盖要求用最少的点(X或Y中都行),让每条边都至少和其中一个点关联。
 Knoig定理:二分图的最小顶点覆盖数等于二分图的最大匹配数。

 (2)DAG图的最小路径覆盖 
 用尽量少的不相交简单路径覆盖有向无环图(DAG)G的所有顶点,这就是DAG图的最小路径覆盖问题。
 结论:DAG图的最小路径覆盖数 = 节点数(n)- 最大匹配数(m)

 (3)二分图的最大独立集
 最大独立集问题: 在N个点的图G中选出m个点,使这m个点两两之间没有边.求m最大值
 结论:二分图的最大独立集数 = 节点数(n)— 最大匹配数(m)

 例如:
#include<iostream>
using namespace std;
/*匈牙利算法:
求解二分图的最大匹配问题
*/
#define N  4                        //左边的节点数
#define M  4                        //右边的节点数
int rightnode[M+1] = {0};           //里面保存与之匹配的左边节点的下标,下标从1开始,0未用
                                    //保存左边节点与右边节点的边的数组
bool line[N + 1][M + 1] = { { 0, 0, 0, 0, 0 },
                            { 0, 1, 1, 0, 0 },
                            { 0, 0, 1, 1, 0 },
                            { 0, 1, 1, 0, 0 },
                            { 0, 0, 0, 1, 0 }
                           };
bool used[M+1] = {false};     //右边节点是否被匹配

//寻找以x为起点的增广路,采用深度遍历的方式  x为左边的某一节点
bool  search_road(int x){
    for (int i = 1; i <=M;i++) //扫描右边的所有节点
    {
        if (line[x][i] == true && used[i] == false){
            used[i] = true;
            int temp = rightnode[i];
            if (temp == 0 || search_road(rightnode[i])){
                 rightnode[i] = x;
                 return true;
            }
        }
    }
    return false;
}
//返回最大的匹配数 
int  getMaxNum(){
    int max = 0;
    for (int i = 1; i <= N;i++)
    {
        for (int j = 1; j <=M; j++) used[j] = false;
        if (search_road(i)) max++;  
    }
    return max;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值