You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

询问最大二分匹配算法的时间复杂度(含经典问题及实现链接)

最大二分匹配:问题场景、实现与时间复杂度解析

嘿,咱们来好好拆解这个经典的二分匹配问题、它的解法,还有你问到的时间复杂度问题~

问题场景回顾

这是个非常典型的二分图匹配场景:

  • 有M名求职者和N个岗位两个不相交的集合
  • 每位求职者只对部分岗位感兴趣(可以理解为二分图里的边)
  • 约束条件:每个岗位仅能接收1名求职者,每名求职者也只能被分配1个岗位
  • 目标:找到能让尽可能多求职者获得工作的分配方案

这本质上就是求二分图的最大匹配——也就是找到最多的边数,保证每个节点只出现在一条边里。

基于DFS的增广路径算法实现

解决这个问题最常用的是基于深度优先搜索(DFS)的增广路径查找算法,核心逻辑是:不断为未匹配的求职者寻找可匹配的岗位,如果目标岗位已经被其他求职者占据,就尝试给那个已匹配的求职者重新找一个岗位(也就是寻找增广路径),直到找不到更多有效匹配为止。

下面是一段可运行的Python实现代码:

def max_bipartite_matching(graph, num_applicants, num_jobs):
    # match_to[j] 记录岗位j当前匹配的求职者编号
    match_to = [-1] * num_jobs
    total_matches = 0

    def dfs(applicant, visited_jobs):
        # 遍历当前求职者感兴趣的所有岗位
        for job in range(num_jobs):
            if graph[applicant][job] and not visited_jobs[job]:
                visited_jobs[job] = True
                # 如果岗位未被匹配,或者已匹配的求职者能找到新岗位
                if match_to[job] == -1 or dfs(match_to[job], visited_jobs):
                    match_to[job] = applicant
                    return True
        return False

    # 逐个处理每个求职者
    for applicant in range(num_applicants):
        visited = [False] * num_jobs
        if dfs(applicant, visited):
            total_matches += 1
    return total_matches

# 示例测试:graph[i][j] = 1 表示求职者i对岗位j感兴趣
sample_graph = [
    [1, 1, 0],
    [1, 0, 1],
    [0, 1, 0]
]
print(max_bipartite_matching(sample_graph, 3, 3))  # 输出3,实现全员匹配

时间复杂度说明

基于DFS的基础算法

这个算法的时间复杂度是 O(V×E)

  • V代表左集合的节点数量(这里就是求职者的数量M)
  • E代表二分图中边的总数量(所有求职者感兴趣的岗位总数)

拆解一下计算逻辑:

  • 我们需要为每个求职者最多执行一次DFS,总共V次DFS调用
  • 每次DFS过程中,最多会遍历所有的边(E条)
  • 两者相乘就得到了O(V×E)的时间复杂度

更高效的进阶算法

如果处理大规模的二分图匹配场景(比如上万级别的节点),可以使用Hopcroft-Karp算法,它的时间复杂度能优化到 O(E×√V),通过批量寻找增广路径来减少重复计算,效率会比基础DFS版本高很多。

内容的提问来源于stack exchange,提问作者Shalini Tomar

火山引擎 最新活动