上一节我们学习了有向图中的最大连通分量. 本节我们来学习二分图. 二分图是一种特殊的图结构, 能够帮助我们高效地解决这些匹配和分配问题. 本文将带你了解二分图的基本概念, 判定方法, 最大匹配算法以及实际应用场景.
环境要求
本文所用样例在Windows 11
以及Ubuntu 24.04
上面编译通过.
- Windows: 使用[Visual Studio],
- Ubuntu: 使用 Clang 18.1.3. (Ubuntu 24.04 系统安装版本)
- GCC 无法编译直接本项目代码, 因为本文代码使用了 C++20 Module, 而 GCC 对此支持不完整.
关于 Module 的更多信息, 请参考我之前的博客: CMake 构建 C++20 Module 实例(使用 MSVC)
本项目工程目录: 图论代码
二分图的基本概念
什么是二分图?
二分图(Bipartite Graph)是指一个图的顶点集可以被分割为两个互不相交的子集 U U U 和 V V V, 并且图中的每一条边都连接 U U U 中的一个顶点和 V V V 中的一个顶点. 换句话说, 二分图中的顶点可以被分成两组, 组内的顶点之间没有边相连, 组间的顶点通过边相连.
二分图的性质
- 如果两个集合中的点分别染成黑色和白色, 可以发现二分图中的每一条边都一定是连接一个黑色点和一个白色点.
- 二分图不存在长度为奇数的环
二分图的判定方法
染色法
染色法是判定二分图最常用的方法. 其核心思想是: 使用两种颜色对图中的顶点进行染色, 相邻顶点颜色不同. 如果能够成功完成染色, 则该图是二分图; 否则, 不是二分图.
算法步骤:
- 选择一个起始顶点, 将其染成颜色 Red.
- 遍历该顶点的所有邻居, 将其染成颜色 Green.
- 递归地对每个邻居的邻居染成颜色 Red, 依此类推.
- 如果在染色过程中发现某个顶点的颜色与相邻顶点颜色相同, 则该图不是二分图.
示例:
现有一个图如下, 请判断是否为二分图:
按照染色法, 从 A 点开始红绿交替染色, 可以得到如下结果:
代码实现
核心代码:
bool ColorDFS(const Graph& graph, std::vector<Color>& colors, Vertex start,
Color color) {
colors[start] = color;