二分图定义:
二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。简而言之,就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集,两个子集内的顶点不相邻。
785. 判断二分图
题目
对于图中的任意两个节点 u 和 v,如果它们之间有一条边直接相连,那么 u 和 v 必须属于不同的集合。
如果给定的无向图连通,那么我们就可以任选一个节点开始,给它染成红色。随后我们对整个图进行遍历,将该节点直接相连的所有节点染成绿色,表示这些节点不能与起始节点属于同一个集合。我们再将这些绿色节点直接相连的所有节点染成红色,以此类推,直到无向图中的每个节点均被染色。
如果我们能够成功染色,那么红色和绿色的节点各属于一个集合,这个无向图就是一个二分图;如果我们未能成功染色,即在染色的过程中,某一时刻访问到了一个已经染色的节点,并且它的颜色与我们将要给它染上的颜色不相同,也就说明这个无向图不是一个二分图。
算法的流程如下:
- 我们任选一个节点开始,将其染成红色,并从该节点开始对整个无向图进行遍历;
- 在遍历的过程中,如果我们通过节点 u 遍历到了节点 v(即 uu 和 vv 在图中有一条边直接相连),那么会有两种情况:
如果 v 未被染色,那么我们将其染成与 u不同的颜色,并对 v 直接相连的节点进行遍历;
如果 v 被染色,并且颜色与 u 相同,那么说明给定的无向图不是二分图。我们可以直接退出遍历并返回False 作为答案。 - 当遍历结束时,说明给定的无向图是二分图,返回 True 作为答案。
可以使用「深度优先搜索」或「广度优先搜索」对无向图进行遍历,下文分别给出了这两种搜索对应的代码。
注意:题目中给定的无向图不一定保证连通,因此我们需要进行多次遍历,直到每一个节点都被染色,或确定答案为False 为止。每次遍历开始时,我们任选一个未被染色的节点,将所有与该节点直接或间接相连的节点进行染色。
方法一: DFS
class Solution {
private:
bool valid;
vector<int> color;
int UNCOLORED=0;
int RED=1;
int GREEN=2;
public:
bool isBipartite(vector<vector<int>>& graph) {
int n=graph.size();
valid=true;
color.assign(n,UNCOLORED);
for(int i=0;i<n&&valid;i++){
if(color[i]==UNCOLORED){
dfs(i,RED,graph);
}
}
return valid;
}
void dfs(int x,int COLOR,vector<vector<int>> &graph){
color[x]=COLOR;
int cNei=(COLOR==RED?GREEN:RED);
for(int nei:graph[x]){
if(color[nei]==UNCOLORED) {
dfs(nei,cNei,graph);
if(!valid){
return;
}
}else if(color[nei]!=cNei){
valid=false;
return;
}
}
}
};
方法二:BFS
class Solution {
private:
vector<int> color;
int UNCOLORED=0;
int RED=1;
int GREEN=2;
public:
bool isBipartite(vector<vector<int>>& graph) {
int n=graph.size();
color.assign(n,UNCOLORED);
for(int i=0;i<n;i++){
if(color[i]==UNCOLORED){
queue<int> qn;
qn.push(i);
color[i]=RED;
while(!qn.empty()){
int k=qn.front();qn.pop();
int cNei=(color[k]==RED?GREEN:RED);
for(int nei:graph[k]){
if(color[nei]==UNCOLORED){
qn.push(nei);
color[nei]=cNei;
}else if(color[nei]!=cNei){
return false;
}
}
}
}
}
return true;
}
};

本文详细介绍了二分图的概念及其在图论中的重要性,探讨了如何使用深度优先搜索(DFS)和广度优先搜索(BFS)来判断一个无向图是否为二分图,提供了具体的算法实现。
1280

被折叠的 条评论
为什么被折叠?



