xxx 最大二分匹配的 Hopcroft-Karp 算法
字数 1677 2025-12-04 10:29:38

xxx 最大二分匹配的 Hopcroft-Karp 算法

题目描述
给定一个二分图 \(G = (V, E)\),其中顶点集 \(V\) 被划分为两个不相交的子集 \(U\)\(V\),边集 \(E\) 仅包含连接 \(U\)\(V\) 的边。目标是找到该二分图的最大匹配,即包含尽可能多的边的子集 \(M \subseteq E\),使得 \(M\) 中任意两条边没有公共顶点。Hopcroft-Karp 算法通过多路径增广策略,在 \(O(\sqrt{|V|} \cdot |E|)\) 时间内高效解决该问题。


解题过程

1. 基本概念回顾

  • 匹配:边的集合,其中任意两条边不共享顶点。
  • 最大匹配:包含边数最多的匹配。
  • 增广路径:一条交替经过匹配边和非匹配边的路径,且起点和终点均为未匹配顶点。增广路径的特性是:将其上的边状态取反(匹配边变为非匹配边,反之亦然)可使匹配大小增加 1。

2. 算法核心思想
Hopcroft-Karp 算法通过以下步骤优化匹配过程:

  • 多路径增广:在单次 BFS 中同时寻找多条最短增广路径,而非一次仅增广一条路径。
  • 分层图构建:使用 BFS 从所有未匹配顶点(通常固定在集合 \(U\) 中)出发,构建分层图,确保每次增广路径长度严格递增。
  • DFS 增广:在分层图上使用 DFS 寻找顶点不相交的增广路径,并一次性更新匹配。

3. 算法详细步骤

步骤 1:初始化

  • 将匹配 \(M\) 初始化为空。
  • 定义距离数组 \(dist\),用于 BFS 中记录顶点到未匹配顶点的最短距离。

步骤 2:多路径增广循环
循环执行以下操作,直到无法找到增广路径:

  1. BFS 构建分层图

    • \(U\) 中所有未匹配顶点出发,进行多源 BFS,仅遍历非匹配边(从 \(U\)\(V\))和匹配边(从 \(V\)\(U\))。
    • 记录每个顶点到起点的最短距离 \(dist\),并标记可达的顶点。
    • 若某个未匹配顶点在 \(V\) 中被到达,则存在增广路径。
  2. DFS 寻找顶点不相交的增广路径

    • \(U\) 中每个未匹配顶点,尝试在分层图上进行 DFS(仅沿距离递减的方向移动),寻找一条到 \(V\) 中未匹配顶点的路径。
    • 每找到一条增广路径,立即更新匹配(路径边状态取反),并确保后续 DFS 不重复使用已匹配的顶点。
  3. 更新匹配

    • 单次循环中找到的所有增广路径被同时应用,匹配大小增加路径数量。

步骤 3:终止与输出

  • 当 BFS 无法到达 \(V\) 中任何未匹配顶点时,算法终止,当前匹配 \(M\) 即为最大匹配。

4. 关键点与复杂度分析

  • 正确性保证:每次增广路径长度严格递增,确保算法在 \(O(\sqrt{|V|})\) 次循环内终止。
  • 时间复杂度
    • 每次 BFS/DFS 耗时 \(O(|E|)\)
    • 总循环次数为 \(O(\sqrt{|V|})\),故总复杂度为 \(O(\sqrt{|V|} \cdot |E|)\)
  • 优势:相比匈牙利算法(\(O(|V| \cdot |E|)\)),Hopcroft-Karp 在稀疏大图上效率显著提升。

5. 实例演示(简略)
考虑二分图:

  • \(U = \{u1, u2, u3\}\), \(V = \{v1, v2, v3\}\)
  • 边集:\((u1,v1), (u1,v2), (u2,v2), (u3,v2), (u3,v3)\)

执行过程

  1. 初始匹配为空。
  2. 第一轮 BFS 找到多条长度为 1 的增广路径(如 \(u1 \to v1\)),通过 DFS 同时增广,匹配大小增至 2。
  3. 第二轮 BFS 找到更长路径(如 \(u3 \to v2 \to u2 \to v?\)),通过调整匹配实现最大匹配(大小为 3)。

通过分层图的约束,算法避免了冗余搜索,快速收敛到最优解。

xxx 最大二分匹配的 Hopcroft-Karp 算法 题目描述 给定一个二分图 \( G = (V, E) \),其中顶点集 \( V \) 被划分为两个不相交的子集 \( U \) 和 \( V \),边集 \( E \) 仅包含连接 \( U \) 和 \( V \) 的边。目标是找到该二分图的 最大匹配 ,即包含尽可能多的边的子集 \( M \subseteq E \),使得 \( M \) 中任意两条边没有公共顶点。Hopcroft-Karp 算法通过多路径增广策略,在 \( O(\sqrt{|V|} \cdot |E|) \) 时间内高效解决该问题。 解题过程 1. 基本概念回顾 匹配 :边的集合,其中任意两条边不共享顶点。 最大匹配 :包含边数最多的匹配。 增广路径 :一条交替经过匹配边和非匹配边的路径,且起点和终点均为未匹配顶点。增广路径的特性是:将其上的边状态取反(匹配边变为非匹配边,反之亦然)可使匹配大小增加 1。 2. 算法核心思想 Hopcroft-Karp 算法通过以下步骤优化匹配过程: 多路径增广 :在单次 BFS 中同时寻找多条最短增广路径,而非一次仅增广一条路径。 分层图构建 :使用 BFS 从所有未匹配顶点(通常固定在集合 \( U \) 中)出发,构建分层图,确保每次增广路径长度严格递增。 DFS 增广 :在分层图上使用 DFS 寻找顶点不相交的增广路径,并一次性更新匹配。 3. 算法详细步骤 步骤 1:初始化 将匹配 \( M \) 初始化为空。 定义距离数组 \( dist \),用于 BFS 中记录顶点到未匹配顶点的最短距离。 步骤 2:多路径增广循环 循环执行以下操作,直到无法找到增广路径: BFS 构建分层图 : 从 \( U \) 中所有未匹配顶点出发,进行多源 BFS,仅遍历非匹配边(从 \( U \) 到 \( V \))和匹配边(从 \( V \) 回 \( U \))。 记录每个顶点到起点的最短距离 \( dist \),并标记可达的顶点。 若某个未匹配顶点在 \( V \) 中被到达,则存在增广路径。 DFS 寻找顶点不相交的增广路径 : 对 \( U \) 中每个未匹配顶点,尝试在分层图上进行 DFS(仅沿距离递减的方向移动),寻找一条到 \( V \) 中未匹配顶点的路径。 每找到一条增广路径,立即更新匹配(路径边状态取反),并确保后续 DFS 不重复使用已匹配的顶点。 更新匹配 : 单次循环中找到的所有增广路径被同时应用,匹配大小增加路径数量。 步骤 3:终止与输出 当 BFS 无法到达 \( V \) 中任何未匹配顶点时,算法终止,当前匹配 \( M \) 即为最大匹配。 4. 关键点与复杂度分析 正确性保证 :每次增广路径长度严格递增,确保算法在 \( O(\sqrt{|V|}) \) 次循环内终止。 时间复杂度 : 每次 BFS/DFS 耗时 \( O(|E|) \)。 总循环次数为 \( O(\sqrt{|V|}) \),故总复杂度为 \( O(\sqrt{|V|} \cdot |E|) \)。 优势 :相比匈牙利算法(\( O(|V| \cdot |E|) \)),Hopcroft-Karp 在稀疏大图上效率显著提升。 5. 实例演示(简略) 考虑二分图: \( U = \{u1, u2, u3\} \), \( V = \{v1, v2, v3\} \) 边集:\( (u1,v1), (u1,v2), (u2,v2), (u3,v2), (u3,v3) \) 执行过程 : 初始匹配为空。 第一轮 BFS 找到多条长度为 1 的增广路径(如 \( u1 \to v1 \)),通过 DFS 同时增广,匹配大小增至 2。 第二轮 BFS 找到更长路径(如 \( u3 \to v2 \to u2 \to v? \)),通过调整匹配实现最大匹配(大小为 3)。 通过分层图的约束,算法避免了冗余搜索,快速收敛到最优解。