二分图
二分图:设
染色法可以用来判别一个图是否为二分图,思想是 DFS,时间复杂度为
一个图是二分图当且仅当图中不含奇数环:
- 显然,二分图的环,起点和 终点前一个点 分属不同子集,矛盾!
- 若一个图不含奇数环,任取一个顶点,根据这个顶点到其他顶点的最短距离的 奇偶性 分组构造即可
- 因此也可以按照顶点到其他顶点最短距离的奇偶性进行 二染色
算法:依次遍历所有顶点,只要 i
没有染色,将它连通块的所有顶点进行二染色(深度优先遍历)。
核心代码:
cpp
bool dfs(int u, int c) {
color[u] = c;
for (int i = h[u]; i != -1; i = ne[i]) {
int j = e[i];
if (!color[j]) {
if (!dfs(j, 3 - c)) {
return false;
}
}
else if (color[j] == c) {
return false;
}
}
return true;
}
- 这里的
dfs()
返回true
表示该点及其连通块中所有点染色成功 - 对于点
u
的所有邻接表上的直接关联的点,都染色成3 - c
,1 染成 2,2 染成 1- 如果
j
尚未染色,深度优先搜索下去,只有后面节点中出现false
才会终止操作 - 这里直接
return dfs(j, 3 - c);
不可以 - 如果
j
已经染色,且染的颜色和u
相同,直接返回false
- 如果
j
已经染色,且染的颜色和u
不同,跳过
- 如果