• 二分图的匹配(未完) yongmou


      二分图是一种特殊类型的图,图中的顶点集被划分成X与Y两个子集,图中每条边的两个端点,一定是一个属于X另一个属于Y。二分图的匹配是求边的一个子集,该子集中的任意两条边都没有公共的端点。含边数最多的匹配即为二分图的最大匹配;如果给二分图的边加权,则边权和最大的匹配即为最佳匹配。

      如果可以以某种方式将研究的对象分成两个互补的集合,而需要求得他们之间满足某种条件的“一一对应”关系时,往往可以抽象出对象以及对象之间的关系,构造二分图,然后利用匹配算法来解决。构造二分图模型,设计匹配算法,并对其算法进行适当的优化。

      另外二分图的覆盖数=匹配数,所以求最小覆盖,可以转化为求最大匹配。其证明比较繁琐,组合数学的书上有。

    1. 采用网络流的方法计算二分图的最大匹配

      将二分图该做成一个网络:增加一个源点s、一个汇点t,由s到X集合中每点增加一条边,由Y中每点到t增加一条边。

      复杂度分析:找到一条增广路径的时间约为O(n*e),最多n次寻找,时间复杂度为O(e*n^2)

    2.计算二分图最大匹配的匈牙利算法

      匈牙利算法是通过构造一颗交错树来计算二分图的最大匹配的。不断的加入增广路径。

      代码:

    #define MAXV 200

    int N, M; //X和Y顶点数分别为N、M
    bool mt[MAXV][MAXV];//二分图, 邻接矩阵

    bool used[MAXV]; //Y集合中的点是否使用
    int link[MAXV]; //匹配边集,其中顶点y所匹配的边为(link[y], y)

    bool check(int x){//判断是否存在由x出发的增广路径
    for(int y=1; y<=M; ++y){
    if(!used[y] && mt[x][y]){
    used[y]
    = true;
    if(link[y] == -1 || check(link[y])){
    link[y]
    = x;
    return true;
    }
    }
    }
    return false;
    }

    int max_match(){
    int x, y, max;;
    for(y=1; y<=M; ++y)
    link[y]
    = -1;
    max
    = 0;
    for(x=1; x<=N; ++x){
    for(y = 1; y<=M; ++y)
    used[y]
    = false;
    if(check(x))
    ++max;
    }
    return max;
    }

    3.计算二分图最佳匹配的KM算法

    (还没看懂,看懂了,再往上写)

  • 相关阅读:
    Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (gbk_chinese_ci,COERCIBLE) for operation '=' 一个解决办法(转载)
    mysql limit用法
    preparedStatement一个小技巧
    两个简单的压力测试代码。
    cookie实现session机制
    java.util.properties用法
    数据库是否使用外键,及视图,索引,存储过程的一些说明(zz)
    某项目要调用现有的100多个DLL 二 最最简单原型的思考
    面试题:红绿灯
    一个简单的封装 .net的日志功能
  • 原文地址:https://www.cnblogs.com/liyongmou/p/1786334.html
Copyright © 2020-2023  润新知