二分图
什么是二分图
若无向图 G=(V,E)G=(V,E) 的顶点集 VV 可以分割为两个互不相交的子集,且图中每条边的两个顶点分别属于不同的子集,则称图 GG 为一个二分图。
简而言之,就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集,两个子集内的顶点不相邻。
二分图的一个等价定义是:不含有「含奇数条边的环」的图
也就是将图中的节点分到两个集合中,满足:只存在由一个集合中的点指向另一个集合中的点的边。(也就是说两个集合中点不互通)
染色法判定二分图
我们找到无向二分图本质上就是一种不存在奇数环的图,使用染色法就可以进行快速判定。
方法步骤:
首先随意选取一个未染色的点进行染色,然后尝试将其相邻的点染成相反的颜色。如果邻接点已经被染色并且现有的染色与它应该被染的颜色不同,那么就说明不是二分图。而如果全部顺利染色完毕,则说明是二分图。染色结束后的情况(记录在数组中)便将图中的所有节点分为了两个部分,即为二分图的两个点集。
1.随意选取点1未染色的点进行染色
2.扫描与他相邻的点2,3,染成相反对颜色
3.枚举每一条边
4.邻接点已经被染色并且现有的染色与它应该被染的颜色不同,那么就说明不是二分图。而如果全部顺利染色完毕,则说明是二分图
dfs版本
代码思路
染色可以使用1和2区分不同颜色,用0表示未染色
遍历所有点,每次将未染色的点进行dfs, 默认染成1或者2
由于某个点染色成功不代表整个图就是二分图,因此只有某个点染色失败才能立刻break/return
染色失败相当于至少存在2个点染了相同的颜色
题目链接: leetcode_ 785. 判断二分图
代码实现
bool dfs(vector<vector<int>>& graph,vector<int>& color, int u, int c) // 将u号点 染成c 颜色 (c = 1 或 2 )
{
color[u] = c;
for(auto e : graph[u])
{
if(color[e] == color[u])
return false;
if(!color[e] && !dfs(graph, color, e, 3 - c))
return false;
}
return true;
}
bool isBipartite(vector<vector<int>>& graph