首页 > 编程语言 >道长的算法笔记:二分图匹配

道长的算法笔记:二分图匹配

时间:2022-11-11 23:00:26浏览次数:49  
标签:二分 匹配 女生 算法 顶点 男生 道长

二分图的概念

 二分图又称作二部图,是图论中的一种特殊模型。假设 \(G=(V,E)\) 是一个无向图,如果顶点 \(V\) 能够分割为两个互不相交的子集 \((S,T)\),并且图中的每条边 \((s,t)\) 所关联的两个顶点 \(a\) 和 \(b\),分别属于这两个不同的顶点集 \((s \in S,t \in T)\),则称图 \(G\) 为一个二分图。

如何判定二分图

 通过BFS染色法,我们能够快速判定一个图是不是二分图。我们随便选择一个顶点出发,将其染为白色,从这个顶点出发将其邻接的顶点全部染成黑色,然后再从黑色的顶点出发,将其邻接未访问的顶点染为白色,如此反复即可。上述的过程出现了三种状态,「未访问」、「白色」与「黑色」,我们可以使用一个数字 \(state\),然后分别使用 \(0、1、2\) 三字数字表示三种不同的状态。这个过程也能使用 DFS 实现。

最大二分图匹配算法

HA算法

 二分图最大匹配是指,给定一个分为左右两个部分的二分图,两个部分内部的顶点连边,现在要求选出跨两个部分的连边(没有公共顶点的连边),并且连边的数量最大。简单来说,我们可以想象这样一个相亲模型,左边是男孩,右边是女孩,我们的身份就是月老,我们要做的事情是令左右两边的男生与女生凑出对数最大。

image

 左右两边匈牙利算法 (HA算法) 主要用于无权图,匈牙利算法也称 KM 算法,KM 其实是作者名字的缩写,其基于匈牙利算法改进得到的。匈牙利算法的运行流程非常简单,我们首先遍历集合 \(S\) 或 \(T\) 任意一个,我们不妨先从左边的、代表男生的集合出发,然后枚举这个男生感兴趣的所有女生。

 例如 \(A\) 感兴趣的女生包括了 \(E、G、H\),我们规定访枚举的顺序是自上而下的,那么访问女生 \(E\),如果女生 \(E\) 也未匹配,那么我们则令\((A,E)\)构成一个配对,然后更新匹配数量。我们可以使用一个数组 \(match\) 记录当前的配对情况的。然后轮男生 \(B\),其感兴趣的女生的只有 \(E\),但是 \(E\) 已经匹配了,于是我们尝试令与\(E\)匹配的 \(A\) 更换匹配对象。显然,由于 \(A\) 感兴趣的女生除了\(E\) 之外仍有 \(G,H\),那么 \(A\) 不选 \(E\),改选 \(G\) 便可君子成人之美的腾出 \(E\),使得 \((B,E)\) 构成一个匹配。当前拥有的匹配包括 \((A,G)、(B,E)\),然后轮到了男生 \(C\),其感兴趣的只有 \(F\),且未被匹配,那么构成匹配 \((C,F)\),然后轮到了男生 \(D\),很不巧,其喜欢的女生 \(G\) 已与 \(A\) 匹配,因而我们再一次令 \(A\) 更换对象,\(A\) 除了 \(E,G\) 之外仍对 \(H\) 感兴趣,因而 \(G\) 最终让给 \(D\), \(A\) 选择 \(H\),那么最终我们得到了四对匹配。

int find(int u){
   for (int v: edges[u]){
       if(!vist[v]){
           vist[v] = 1;
           if(!match[v] || find(match[v])){
               match[v] = u;
               return true;
           }
       }
   }
   return false;
}

 基于DFS实现的匈牙利算法,其实非常简洁,选择\(S\)或\(T\)其中一个集合开始的遍历,进入一个未访问的顶点,如果没有匹配,令其匹配,如果已经匹配,尝试令其匹配对象更换对象,腾出空位。然而如果二分图较大,尝试「更换匹配,腾出空位」这个过程的递归深度有可能会非常之深,寻找替代对象的搜索路径会在 \(S\)、\(T\)两个集合之间反复交错。


KM算法

标签:二分,匹配,女生,算法,顶点,男生,道长
From: https://www.cnblogs.com/taoist-chen/p/16882323.html

相关文章

  • 献芹奏曝-Python面试题-算法-DFS&BFS
    上一篇:献芹奏曝-Python面试题    开篇的话:本文目的是收集和归纳力扣上的算法题,希望用python语言,竭我所能做到思路最清奇、代码最简洁、方法最广泛、性能最高效,了解......
  • 算法笔记(三):数学问题
    最大公约数辗转相除法intgcd(inta,intb){ if(b==0)returna; returngcd(b,a%b);}最小公倍数根据最大公约数得出最小公倍数步骤:先求得a与b的最大公......
  • 算法笔记(二):知识点补充
    万能头文件#include<bits/stdc++.h>数组最大范围int型一维数组:小于4e8,即4亿int型二维数组:小于2e4,即2万数据类型范围int和long都是用32位来存储最大值和最小值分......
  • Floyd算法的关键点
    Floyd算法的代码很简单,就是三个for这个算法最重要的地方就是中转点的枚举for(intk=1;k<=n;k++)for(inti=1;i<=n;i++)for(intj=1;j<=n;j++)g[i][j]=max(g[i][j],g[i......
  • 旋转门数据压缩算法在PostgreSQL中的实现 - 流式压缩在物联网、监控、传感器等场景的
      背景在物联网、监控、传感器、金融等应用领域,数据在时间维度上流式的产生,而且数据量非常庞大。例如我们经常看到的性能监控视图,就是很多点在时间维度上描绘的曲线......
  • 回溯算法dfs: lc46全排列 lc47全排列ll
    result=[] defbacktrack(路径,选择列表):if满足结束条件:result.add(路径)returnfor选择in选择列表:做选择backtrack(路径,选择列表)撤销选择 46全......
  • 实验三:朴素贝叶斯算法实验
    【实验目的】理解朴素贝叶斯算法原理,掌握朴素贝叶斯算法框架。【实验内容】针对下表中的数据,编写python程序实现朴素贝叶斯算法(不使用sklearn包),对输入数据进行预测;熟悉s......
  • Yolo轻量级网络,超轻算法在各硬件可实现工业级检测效果(附源代码)
    计算机视觉研究院专栏作者:Edison_G目标检测是现在最热门的研究课题,也一直是工业界重点研究的对象,最近几年内,也出现了各种各样的检测框架,所属于YOLO系列是最经典也是目前被大......
  • 最短路径及最低成本算法实现模型
     在vs环境下进行的操作用两种方法分别模拟实现公园导航1.Dijkstra算法按路径长度递增次序来产生最短路径算法;  dist【】距离,path【】前结点  ①初始化......
  • space 动态布局算法(vue3-ts、setup)
    动态布局组件演示效果<template><ulclass="space_ulflex-row":style="{'padding-top':`${hs}px`,'padding-left':`${ws}px`}"......