poj3041二分图的最大匹配匈牙利算法

来源:互联网 发布:数据分析系统 架构 编辑:程序博客网 时间:2024/04/29 21:26

题意:一艘飞船想经过一个有小行星的区域,那么他需要用炮把这些行星都干掉,才能安全过去,这个炮比较nb它可以一次干掉一行,或者一列。然后紧接着给出一个矩阵,并给出了行星在这个矩阵里的坐标。然后问你飞船经过这个区域所需要开的最少的炮是多少?(要全部干掉所有的小行星)

 

一、二分图的匹配问题

    给定一个无向图G = (V,E),一个匹配是一个边的子集合 M⊆E,且满足对所有顶点v∈V,M一条边与v关联。如果M中某条边与v关联,则顶点v∈V被匹配,否则说v是无匹配的。最大匹配是最大势的匹配,也就是说,是满足对任意匹配M',有|M|≥|M'|的匹配M。假定顶点集合可被划分为V = L∪R(通俗的说就是把这个图的顶点集合划分为x集合和y集合),假定L和R是不相交的,且E中的所有边得一个端点在R中,另一个端点在L中,进一步假设V中的每个顶点至少有一条关联的边。这是二分图的匹配图

二分图的最大匹配问题有着许多实际的应用。例如,把一个机器集合L和要同时执行的任务与集合R相匹配、E中有边(u,v),就说明一台机器u∈能够完成一项特定的任务v∈R,最大的匹配可以为尽可能多的机器提供任务。

 以上文字是对二分图匹配的简要说明。如果看不懂在看看下面这个

         

算法最基本轮廓:

   

  1. 置边集M为空(初始化,谁和谁都没连着)
  2. 选择一个新的原点寻找增广路
  3. 重复(2)操作直到找不出增广路径为止(2,3步骤构成一个循环)
  1. 初始化(清空)
  2. 从A所连接的点中找到一个未在本次循环中搜索过的点2,并将2标记为搜索过,因为2没有被连接过,匹配A2
  3. 结束上次,开始新的循环,将所有点标记为未搜索过
  4. 搜索B,找到一个未在本次循环中搜索过的点2,标记为搜索过
  5. 发现2被匹配过,从2的父亲A寻找增广路,递归搜索A{从A所连接的点中找到一个未在本次循环中搜索过的点5(1已经标记为绿色),将5标记为搜索过,因为5没有被匹配过,匹配A5}找到增广路(此处为增广路的关键
  6. 结束上次,开始新的循环,将所有点标记为未搜索过
  7. 搜索C,找到一个未在本次循环中搜索过的点1,并将1标记为搜索过,发现1未被匹配过,匹配C1
  8. 结束上次,开始新的循环,将所有点标记为未搜索过
  9. 搜索D,找到一个未在本次循环中搜索过的点1,并将1标记为搜索过,发现1被匹配过,递归搜索1的源C寻找增广路
  10. {搜索C,找到一个未在本次循环中搜索过的点5,标记为搜索过,发现5被匹配,进一步返现没有其他可连接点,返回找不到增广路}返回第9步
  11. 搜索D,找到一个未在本次循环中搜索过的点2,发现2被匹配,递归搜索2的源B寻找增广路
  12. {搜索B,找到一个未在本次循环中搜索过的点3,并将3标记为搜索过,发现3未被匹配,匹配B3返回找到}既然B另寻新欢,匹配D2
  13. 结束上次,开始新的循环,将所有点标记为未搜索过,递归搜索D寻找增广路
  14. 搜索E,找到一个未在本次循环中搜索过的点2,并将2标记为搜索过,发现2被匹配过,递归搜索2的源D寻找增广路
  15. {搜索D,发现1,5均被匹配过,返回找不到增广路}
  16. E无其他可连接节点,放弃E,E后无后续节点,已经遍历A-E,结束算法            
  17. gif演示                                      

在上段代码  ,poj3041

 

原创粉丝点击