【算法】匈牙利算法 二分图最大匹配题模板

【任务】

给定一个二分图,用匈牙利算法求这个二分图的最大匹配数。

【说明】

求最大匹配,那么我们希望每一个在左边的点都尽量找到右边的一个点和它匹配。

我们一次枚举左边的点x的所有出边指向的点y,

若y之前没有被匹配,那么(x,y)就是一对合法的匹配,我们将匹配数加一,

否则我们试图给原来匹配的y和x'重新找一个匹配,如果x'匹配成功,那么(x,y)就可以新增为一对合法的匹配。

给x'寻找匹配的过程可以递归解决。

【接口】

int hungary();

复杂度O(|E|*sqrt(|V|))

输入: n    全局变量,左侧的点数

      g    全局变量,g[i]表示与左边点i相连的右边的点

输出:tot     最大匹配数

   from    全局变量,from[i]表示最大匹配图中与左边点i相连的边 

【代码】

//输入:
const  int MAXN = 555; // 数组长度
int n = 200; //n表示左侧的点数
vector <int> g[MAXN];  // 表示与左边点i相连的右边点

//输出:
int from[MAXN];//表示最大匹配中与左边点i相连的边
int tot;  // 二分图最大匹配数


bool use[MAXN]; // 左边点的使用标记


//匈牙利算法 模板题 ,match和hungary见小红书ACM国际大学生程序设计竞赛 算法与实现
bool match(int x){
    for(int i = 0;i < g[x].size(); ++i){
        if(!use[g[x][i]]){
            use[g[x][i]] = true;
            if(from[g[x][i]] == -1 || match(from[g[x][i]])){
                from[g[x][i]] = x;
                return true;
            }
        }
    }
    return false;
}

int hungary(){
    tot = 0;
    memset(from,255,sizeof(from));
    for(int i = 1;i <= n; i++){
        memset(use,0,sizeof(use));
        if(match(i)) ++tot;
    }
    return tot;
}

这个我打算写给自己写题学习时用的,发出来供大家参考。

样题:http://www.cnblogs.com/zhangjiuding/p/7538564.html

原文地址:https://www.cnblogs.com/zhangjiuding/p/7538876.html