二分图(Bipartite Graph)的判定及其应用
字数 1476 2025-12-10 06:43:09
二分图(Bipartite Graph)的判定及其应用
一、问题描述
给定一个无向图(可能包含多个连通分量),判断该图是否为二分图(Bipartite Graph)。
- 二分图定义:图中的所有顶点可以被划分到两个互不相交的集合 U 和 V 中,使得图中任意一条边的两个端点分别属于 U 和 V(即同集合内的顶点之间没有边)。
- 等价条件:图可以被二着色(用两种颜色对顶点染色),使得任意相邻顶点颜色不同。若存在奇环(长度为奇数的环),则图不是二分图。
输入形式:通常给定图的顶点数 n 和边列表(如邻接表或邻接矩阵)。
输出:布尔值,表示是否为二分图。
二、理解核心性质
关键结论:
一个图是二分图 ⇔ 图中不存在奇环。
- 偶环(如长度为 4 的环)可以被二着色,但奇环无法用两种颜色交替染色(首尾颜色冲突)。
- 因此,判定二分图等价于检测是否存在奇环。
三、判定方法:染色法(BFS/DFS)
1. 算法思路
- 初始化所有顶点为“未染色”(例如用 0 表示)。
- 遍历每个连通分量(避免非连通图漏判):
- 从一个未染色的顶点开始,将其染成颜色 1。
- 对相邻顶点递归或迭代染色:
- 若相邻顶点未染色,则染成相反颜色(颜色 2)。
- 若相邻顶点已染色,且颜色与当前顶点相同,则发现冲突 → 不是二分图。
- 若所有顶点成功染色且无冲突,则是二分图。
2. 步骤详解(以 BFS 为例)
示例图(邻接表表示):
顶点 0, 1, 2, 3;边: (0,1), (1,2), (2,3), (3,0)
该图是一个长度为 4 的环(偶环),应是二分图。
过程:
- 初始化颜色数组 color[],全为 0(未染色)。
- 遍历每个顶点,对未染色的顶点启动 BFS:
- 起点为顶点 0,染成 1(入队列)。
- 队列弹出 0,检查邻居 1 和 3:
- 邻居 1 未染色 → 染成 -1,入队。
- 邻居 3 未染色 → 染成 -1,入队。
- 弹出 1,邻居 0 颜色为 1(与 1 的颜色 -1 不同,合法),邻居 2 未染色 → 染成 1,入队。
- 弹出 3,邻居 0 颜色 1(与 3 的颜色 -1 不同,合法),邻居 2 颜色 1(与 3 的颜色 -1 不同,合法)。
- 弹出 2,邻居 1 颜色 -1(合法),邻居 3 颜色 -1(合法)。
- 未发现冲突,判定为二分图。
时间复杂度:O(V + E),其中 V 为顶点数,E 为边数(遍历所有顶点和边一次)。
四、代码实现(Python)
from collections import deque
def isBipartite(graph):
n = len(graph)
color = [0] * n # 0: 未染色, 1: 颜色A, -1: 颜色B
for i in range(n):
if color[i] != 0:
continue
# BFS 遍历连通分量
queue = deque([i])
color[i] = 1
while queue:
node = queue.popleft()
for neighbor in graph[node]:
if color[neighbor] == 0:
color[neighbor] = -color[node]
queue.append(neighbor)
elif color[neighbor] == color[node]:
return False
return True
# 示例:graph 是邻接表形式
graph = [[1,3], [0,2], [1,3], [0,2]]
print(isBipartite(graph)) # True(偶环,是二分图)
graph_with_odd_cycle = [[1,2], [0,2], [0,1]]
print(isBipartite(graph_with_odd_cycle)) # False(三角形奇环)
五、常见变形与扩展
-
DFS 实现:递归染色,逻辑与 BFS 类似。
-
并查集解法(扩展思路):
- 对于每条边 (u, v),将 u 的所有邻居合并到同一个集合,若发现 u 和 v 在同一集合则冲突。
- 但需注意实现细节,通常染色法更直观。
-
二分图匹配问题:
- 匈牙利算法(Hungarian Algorithm)用于求解二分图最大匹配(如任务分配、婚配问题)。
- 判定二分图是使用匈牙利算法的前提。
六、典型应用场景
- 广告投放与用户匹配:用户和广告分为两类,边表示用户可能点击的广告,求最大匹配。
- 任务调度:工人与任务分为两类,边表示工人能完成的任务,求最大匹配。
- 社交网络分析:判断网络是否可以划分为两个阵营(如敌友关系)。
- 电路设计:某些布局问题可抽象为二分图着色。
七、总结要点
- 核心:二分图判定 ⇔ 二染色 ⇔ 无奇环。
- 算法:BFS/DFS 染色,时间复杂度 O(V+E)。
- 注意:非连通图需遍历所有连通分量。
- 扩展:判定后常需进一步求最大匹配(匈牙利算法)。