zoukankan      html  css  js  c++  java
  • 【算法】匈牙利算法 二分图最大匹配题模板

    【任务】

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

    【说明】

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

    我们一次枚举左边的点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

  • 相关阅读:
    面向对象的思维
    343. 整数拆分
    413. 等差数列划分
    303. 区域和检索
    62. 不同路径
    char类型与int类型相加
    mybatis里面resultmap的问题
    easyui的datagrid如何获取一个对象里面的成员对象里面的属性?
    ==和equls的区别
    泛型的使用思想
  • 原文地址:https://www.cnblogs.com/zhangjiuding/p/7538876.html
Copyright © 2011-2022 走看看