染色法判定二分图
-
-
- 一、二分图
- 二、染色法
-
- 1.算法实现思路
- 2.DFS深度优先遍历代码实现
- 3.BFS广度优先遍历代码实现
一、二分图
- 一定不含有奇数环,可能包含长度为偶数的环, 不一定是连通图
二分图是图论中的一种特殊模型。设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图。准确地说:把一个图的顶点划分为两个不相交子集 ,使得每一条边都分别连接两个集合中的顶点。如果存在这样的划分,则此图为一个二分图,如下图所示的全都是二分图:
关于二分图有一个重要的定理:G为二分图的充要条件是G中的每一个环的长度都是偶数 在这里就不证明了。
二、染色法
1.算法实现思路
- 我们规定1或2代表一个点属于两个集合。
- 首先我们任选一个点染色成1,把和它相连的所有点染色成2。
- 然后再把所有和染色成2的点相邻的点染色成1
- 在每一次染色点时首先要判断一下这个点是否被染色过,如果被染色过并且和上一个点颜色相同,则代表染色失败,该图不是二分图。
2.DFS深度优先遍历代码实现
代码思路:
- 染色可以使用1和2区分不同颜色,用0表示未染色
- 遍历所有点,每次将未染色的点进行dfs, 默认染成1或者2
- 由于某个点染色成功不代表整个图就是二分图,因此只有某个点染色失败才能立刻break/return
//#pragma GCC optimize(2)
#include
#include
#include
#include
#include
#include
#include
#include
#include
3.BFS广度优先遍历代码实现
代码思路
- 颜色 1 和 2 表示不同颜色, 0 表示 未染色
- 定义queue是存PII,表示 <点编号, 颜色>,
- 同理,遍历所有点, 将未染色的点都进行bfs
- 队列初始化将第i个点入队, 默认颜色可以是1或2
- while (队列不空)
- 每次获取队头t, 并遍历队头t的所有邻边
- 若邻边的点未染色则染上与队头t相反的颜色,并添加到队列
- 若邻边的点已经染色且与队头t的颜色相同, 则返回false
//#pragma GCC optimize(2)
#include
#include
#include
#include
#include
#include
#include
#include
#include
作者:Avalon Demerzel,喜欢我的博客就点个赞吧,更多图论与数据结构知识点请见作者专栏《图论与数据结构》