二分匹配常见的集中情形:最大匹配,最佳匹配。
最小覆盖: 最小覆盖要求用最少的点(X 集合或 Y 集合的都行)让每条边都至少和其中一个点关联。可以证明:最少的点(即覆盖数)= 最大匹配数,这就是所谓 Konig 定理。
最小路径覆盖:用尽量少的不相交简单路径覆盖有向无环图 G 的所有结点。解决此类问题可以建立一个二分图模型。把所有顶点 i 拆成两个:X 结点集中的 i 和 Y 结点集中的 i',如果有边 i->j,则在二分图中引入边 i->j',设二分图最大匹配为 m,则结果就是 n-m。
最大独立集问题:在 N 个点的图 G 中选出 m 个点,使这 m 个点两两之间没有边.求 m 最大值.如果图 G 满足二分图条件,则可以用二分图匹配来做.最大独立集点数 = N - 最大匹配数
最佳匹配的意思是说边是有权值的,要找到一个匹配使得权值尽可能大。
寻找最大匹配和最佳匹配的算法可以参考卢开澄的那本书《图论及其应用》,书上寻找最佳匹配的算法就是 KM 算法。
http://www.cppblog.com/abilitytao/archive/2009/10/21/99124.aspx
http://blog.csdn.net/logic_nut/archive/2009/08/07/4420542.aspx
http://blog.csdn.net/AllenLSY/archive/2009/12/14/5004360.aspx
匈牙利算法
http://blog.csdn.net/liaojinyu282/archive/2009/12/15/5005690.aspx
伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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的对应项出有可增广路) 匹配数++; } 输出 匹配数; } |
最小路径覆盖
http://blog.csdn.net/logic_nut/archive/2009/08/07/4421307.aspx
最佳匹配详细代码
http://blog.csdn.net/Rappy/archive/2007/09/19/1790647.aspx
KM 算法
http://blog.csdn.net/yulin11/archive/2009/07/28/4385207.aspx
http://blog.csdn.net/power721/archive/2009/09/17/4560148.aspx
使得“总和最小”的最佳匹配
http://blog.csdn.net/wilxy/archive/2007/12/10/1928412.aspx
http://blog.csdn.net/yuhailin060/archive/2010/01/06/5135101.aspx
例题:
http://www.cppblog.com/abilitytao/archive/2009/10/21/99124.aspx
http://www.byvoid.com/blog/match-km/